文章目录:
- Linux环境变量介绍
- 常用的环境变量
- 如何查看环境变量
- 命令搜索路径PATH
- 与环境变量相关的命令
- 环境变量的组织方式
- 通过代码的方式获取环境变量
- 通过系统调用获取或设置环境变量
- 环境变量的全局属性(继承)
Linux环境变量介绍
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。🎯
在 Linux 系统中,环境变量可以设置为用于执行 shell、bash 或 任何应用的全局变量或本地变量。即 Linux 环境变量只是一个名称,并且相同的名称包含一些值或路径。
例如:我们编写的 c/c++ 代码在链接的时候,是不知道所链接的动态静态库在哪里的,但是照样可以链接成功,生成可执行程序,因为相关的环境变量会帮助编译器进行查找。
环境变量通常具有某些特殊的用途,在系统中通常具有全局属性。
常用的环境变量
- USER:显示当前用户的名称
- PATH:指定命令的搜索路径
- HOME:指定用户的主工作目录(即用户登录到 Linux 系统时,默认的目录)
- SHELL:给出当前用户 shell 程序的位置,它的值通常是 /bin/bash
- HOSTNAME:主机名
- UID:显示当前用户的 ID
- LANG:给出默认的系统语言
如下所示:
如何查看环境变量
可以通过 echo命令 来查看环境变量:
echo $NAME // NAME代表需要查看的变量的名称
命令搜索路径PATH
❓这里有一个问题?在 Linux 下,为什么执行我们自己的可执行程序需要在前面加上 ./
,而执行系统中的相关指令(如:ls、pwd等)就不用呢?
需要执行一个可执行程序,首先要找到该程序在哪里。系统能够执行 ls、pwd等 指令,说明操作系统能够找到这些命令的路径,而我们自己程序的路径,系统是不知道的,因此,我们需要加上 ./
来告诉操作系统该可执行程序在当前目录下。
那么系统是怎么知道 ls 等指令的路径的呢?操作系统通过环境变量 PATH 来查找 ls 等指令的路径,我们可以查看环境变量 PATH 的内容,如下所示:
PATH 中存在很多的路径,每个路径由冒号分开。当在命令行中输入指令后,系统会在环境变量 PATH 中依次查看每个路径下是否有这个指令,若有便直接运行,否则报错(command not found)。
❓我们自己的程序是否能够不带路径直接执行呢?如何解决这个问题?
方法一:将我们的可执行程序拷贝到环境变量 PATH 的其中一个路径中
sudo cp 可执行程序名称 环境变量PATH中的其中一个路径
一般情况下,不推荐此方法。
方法二:将该可执行程序所在的路径添加到环境变量 PATH 中
export PATH=$PATH:当前可执行程序的路径
与环境变量相关的命令
环境变量是系统级别上可用的变量。相同的变量将用于 shell 或 应用程序作业。我们可以在 Linux 中使用环境变量,如:echo、export、env、unset、set等。
echo:显示某个环境变量的值
export:用于设置一个新的环境变量。这个变量是临时的,如果会话退出或关闭,那么这个变量的作用域将会消失。
env:使用不带参的 env 命令时,它会打印系统中所有的环境变量。
set :set 命令用于设置 Linux 的环境变量。当不带参数的使用 set 命令时,他将显示本地定义的 shell 变量和环境变量。
unset:清除环境变量。
环境变量的组织方式
以上是 Linux 中,环境变量的组织方式。每个程序都会有一张环境表,环境表是一个字符指针数组,每个指针指向一个以 ‘\0’ 结尾的环境字符串。
通过代码的方式获取环境变量
通过 main 函数的第三个参数获取
❓在这里,我们思考一个问题。main 函数可以带参数吗?最多能带几个参数?
main 函数是可以带三个参数的,在一般情况下,我们都没有用到。
首先,来看看 main 函数的前两个参数。
在 Linux 下,通过以下代码,测试 main 函数参数的作用及意义。
#include<stdio.h>
int main(int argc,char* argv[])
{
for(int i=0;i<argc;i++)
{
printf("argv[%d]:%s\n",i,argv[i]);
}
return 0;
}
代码运行结果如下:
通过以上代码和运行结果可以看出,同一个程序,通过传递不同的参数,让同一个程序有不同的执行逻辑和执行结果。main 函数的第二个参数是一个字符指针数组,指针数组中的第一个字符指针存储的是可执行程序的地址,其余指针指向命令行中所给出的选项(每个选项以空格分开),最后以一个空指针结尾。main 函数的第一个参数 argc 代表字符指针数组中的有效元素个数。
✨理解 main 函数中两个参数的意义之后,下面尝试实现一个简单的命令行版 + -*/ 的计算器,加深对 main 函数参数的理解及应用:
要求:在命令行中输入 可执行程序 -选项 number1 number2
例如:./process -a 5 7
,则运行程序后输出 5 + 7 = 12
。
// 写一个命令行版简易计算器
// ./process -a 10 20
// 10 + 20 = 30
// ./process -s 10 20
// 10 - 20 = -10
int main(int argc,char *argv[])
{
// 判断指令是否输入正确,若输入不正确,则提示规则
if(argc != 4)
{
printf("Usage:%s [-a][-s][-m][-d] num1 num2\n",argv[0]);
return 0;
}
// 将输入的数据转换为整形
int x=atoi(argv[2]);
int y=atoi(argv[3]);
if(strcmp("-a",argv[1])==0)
{
printf("%d + %d = %d\n",x,y,x+y);
}
else if(strcmp("-s",argv[1])==0)
{
printf("%d - %d = %d\n",x,y,x-y);
}
else if(strcmp("-m",argv[1])==0)
{
printf("%d * %d = %d\n",x,y,x*y);
}
else if(strcmp("-d",argv[1])==0)
{
if(y==0)
printf("除0错误!\n");
else
printf("%d / %d = %d\n",x,y,x/y);
}
else
{
printf("Usage:%s [-a][-s][-m][-d] num1 num2\n",argv[0]);
}
return 0;
}
代码测试如下:
🧨通过上述的验证测试,我们了解了 main 函数前两个参数是干什么的。而 main 函数最多可以有三个参数,那么第三个参数是什么呢?存在的意义是什么?
main 函数的第三个参数实际上是一个环境变量列表,可以通过 main 函数的第三个参数来获取系统中的环境变量。所以,我们可以使用以下代码获取系统的环境变量:
int main(int argc,char *argv[],char *env[])
{
// env字符指针数组中,最后一个指针为空
for(int i=0;env[i];++i)
{
printf("env[%d]:%s\n",i,env[i]);
}
return 0;
}
通过第三方变量 environ 获取
Linux 中 environ 变量是一个 char** 类型,存储着系统的环境变量。
可以使用以下代码来遍历环境变量:
#include<stdio.h>
int main(int argc,char *argv[])
{
extern char **environ;
for(int i=0;environ[i];++i)
{
printf("%s\n",environ[i]);
}
return 0;
}
注意:libc 中定义的全局变量 environ 指向环境变量表,environ 没有包含在任何头文件中,所以使用时需要加上 extern 进行声明。
通过系统调用获取或设置环境变量
🎈 常用 getenv 和 putenv 函数来访问特定的环境变量。
C语言 getenv() 函数:获取环境变量
头文件:
#include<stdlib.h>
定义函数:
char *getenv(const char *name);
函数描述: getenv() 函数搜索环境变量列表以查找环境变量名,并返回指向相应字符串的指针。环境变量的格式为 name=value。
返回值: getenv() 函数返回一个指向环境中值的指针,找不到则返回 NULL。
示例:
1 #include<stdio.h>
2 #include<stdlib.h>
3
4
5 int main()
6 {
7 printf("%s\n",getenv("PATH"));
8 return 0;
9 }
运行结果:
C语言 putenv() 函数:改变或增加环境变量
头文件:
#include<stdlib.h>
定义函数:
int putenv(const char *string);
函数描述: putenv() 函数的作用是增加或改变环境变量的值。参数字符串的形式是 name=value 。如果 name 在环境中不存在,则增加 name=value 到环境中。如果 name 存在,则环境中 name 的值被改为 value。由 string 指向的字符串成为环境的一部分,因此改变字符串将改变环境。
返回值: putenv() 函数成功时返回0,发生错误时返回非零。如果发生错误,则设置 errno 以指示原因。
错误: ENOMEM 分配新环境的空间不足。
示例:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *p;
if((p = getenv("USER")))
printf("USER = %s\n",p);
putenv("USER=test");
printf("USER+5s\n",getenv("USER"));
return 0;
}
运行结果:
环境变量的全局属性(继承)
- 环境变量通常具有全局属性,可以被子进程继承。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{
char *env = getenv("MYVAL");
pid_t id = fork();
if(id == 0)
{
printf("%s\n",getenv("MYVAL"));
}
return 0;
}
运行结果:
如上所示,当导入环境变量后。fork() 创建的子进程依旧可以获取该环境变量的值,说明环境变量具有全局属性,被子进程继承了。
继承:当父进程创建子进程时,子进程继承父进程拥有的所有环境变量和值。
我们对环境变量进行了初步的了解。环境变量对于在 Linux 环境中导出路径或设置特定值非常重要。它将为第三方软件或应用程序导入,以访问 Linux 环境并执行作业。