环境变量
了解PATH
提出问题:
我写的可执行程序,与系统的可执行程序都是可执行程序,那么为什么执行系统的可执行程序不需要带 (./)就能直接运行,而我自己写的可执行程序需要带(./)才能运行。
我想要我的可执行程序也像指令一样,不需要带(./)也能直接运行,前提是我们要先找到这个程序。
(./Test)这个(./)代表的是当前路径,这样有路径才能找到程序。而系统的指令是由系统自己找的
添加为指令方法:
sudo cp (可执行文件) /usr/bin/
我们只需要将可执行程序添加到系统路径中,这样就能直接使用了,但是这种方法不建议使用,因为你的指令没有经过测试,会污染指令池。
删掉可执行文件:
sudo rm /usr/bin/可执行文件
另一种方法:添加路径进入PATH环境变量中
PATH : 指定命令的搜索路径
查看环境变量方法:
echo $NAME //NAME:你的环境变量名称
这些以每个冒号隔开的路径就是我们的指令搜索的路径,我们使用指令的时候会在这些路径里面一个一个取寻找,找到了就执行,没找到则报错。
将路径导入到PATH环境变量里面:
export PATH=$PATH:(pwd:你所在的路径)
现在我们执行不用带路径了。
你写的可执行程序不能直接像指令一样不带路径执行,是因为你写的可执行程序的路径不在系统的默认搜索路径下面,而系统的指令能够执行,是因为PATH环境变量本来就默认带了系统的指令路径
什么是环境变量?
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
Linux 中的环境变量是动态命名值,用于存储有关系统及其上运行的应用程序的信息。它们可用于自定义应用程序的行为、设置默认设置以及存储重要信息,例如用户的主目录或可执行文件的路径。
环境变量通常在用户的 shell 启动文件中设置,例如 或 。它们也可以基于每个应用程序进行设置,也可以在文件中在系统范围内设置。
设置环境变量后,它将可用于从当前 shell 启动的所有应用程序。您可以查看当前使用该命令设置的所有环境变量的列表。
显示所有环境变量:
env
环境变量其实是为了满足操作系统不同场景预先在系统内设置的一大批的全局变量,这些变量在整个bash中都能一直访问到
环境变量是一种存储可由程序和脚本访问的数据的方法。它们通常用于存储密码、数据库连接字符串和其他敏感信息等内容。环境变量在操作系统中设置,然后可用于在同一台计算机上运行的所有程序。
环境变量可用于存储各种数据。环境变量的一些常见用途包括:
- 存储密码:环境变量可用于存储应用程序和服务的密码。这可以通过防止密码以纯文本形式存储在计算机上来帮助确保密码安全。
- 存储数据库连接字符串:环境变量可用于存储数据库连接字符串。这有助于确保数据库连接信息的安全,并简化数据库连接管理。
- 存储其他敏感信息:环境变量可用于存储其他敏感信息,例如 API 密钥和 OAuth 令牌。这有助于确保此信息的安全,并更轻松地管理对应用程序和服务的访问。
- 环境变量是一个强大的工具,可用于以安全的方式存储和访问数据。它们是开发人员和系统管理员的宝贵工具。
以下是使用环境变量的一些其他提示:
- 对环境变量使用描述性名称。这将使您更容易理解变量的用途。
- 对环境变量使用强密码。这将有助于确保您的数据安全。
- 不要将敏感信息存储在公众可访问的环境变量中。例如,不要将密码存储在非管理员用户可访问的环境变量中。
- 使用版本控制系统跟踪对环境变量的更改。这将有助于确保您不会意外删除或覆盖重要的环境变量。
使用环境变量
我们在代码里面,也能拿到环境变量:
我们写入下面的程序:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #defile USER "USER"
4
5 int main()
6 {
7 char* who = getenv(USER);
8 printf("user:%s\n",who);
9 return 0;
10 }
运行结果:
环境变量USER信息:
我们先将用户转换为root:
USER环境变量的最大意义,可以标识当前使用的Linux用户
我们更改代码为下:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #define USER "USER"
5
6 int main()
7 {
8 char* who = getenv(USER);
9 if(strcmp(who,"root")==0)
10 {
11 printf("user:%s\n",who);
12 printf("user:%s\n",who);
13 }
14 else
15 {
16 printf("权限不足!!\n");
17 }
18 return 0;
19 }
运行结果:
我们 su - 重新登陆为root时:
使用sudo命令也可以执行:
我们在有时候使用某个命令发现是权限不足的时候,其实在底层也是差不多的。通过它的拥有者所属组权限判断,写指令的人会在指令内部进行判断你是否有权限使用。
我们还可以这样使用:
环境变量类似全局变量
且看下面代码:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #define USER "USER"
5 #define MY_ENV "myvalue"
6 int main()
7 {
8 //char* who = getenv(USER);
9 char* myenv = getenv(MY_ENV);
10 if(myenv == NULL)
11 {
12 printf("%s:not found\n",MY_ENV);
13 return 1;
14 }
15 printf("%s=%s\n",MY_ENV,myenv);
16 return 0;
17 }
代码结果:我们并没有发现我们定义在外面的myvalue,说明myvalue不是环境变量
设置一个新的环境变量:
export (名字)
同时我们重新运行之前上面代码:
我们还可以这样使用export:
取消环境变量:
./Test
- bash是一个系统进程,而我们写的Test也会变成一个子进程(fork),环境变量具有全局属性,原因是它会被子进程继承下去。
- 为什么要继承下去?
为了不同的应用场景:让bash帮我找指令路径,身份认证
myvalue=12345
- 本地变量,只能在当前进程(bash)内有效
我们在使用指令的时候,比如ls 、cat等都不需要带路径,是因为有PWD这个环境变量在维护你所在的路径,你的路径变了,PWD维护的路径也会跟着变化,所以我们使用系统指令不需要额外添加绝对或相对路径,因为有PWD这个环境变量可以得知你所在的路径,直接使用即可
写一个pwd命令:
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #define MYPWD "PWD"
6
7 int main()
8 {
9 printf("%s\n",getenv(MYPWD));
10 return 0;
11 }
系统自带环境变量示例
环境变量是一个强大的工具,可用于自定义应用程序和系统的行为。通过了解环境变量的工作原理,您可以使您的 Linux 系统更高效、更用户友好。
环境变量相关的命令:
- echo: 显示某个环境变量值
- export: 设置一个新的环境变量
- env: 显示所有环境变量
- unset: 清除环境变量
- set: 显示本地定义的shell变量和环境变量
环境变量的一些示例:
- PATH:此变量存储搜索可执行文件的目录列表。
- HOME:此变量存储当前用户的主目录。
- SHELL:此变量存储当前用户 shell 的路径。
- LANG:此变量存储当前语言和区域设置。
- MAIL:此变量存储当前用户邮件的位置。
您可以使用环境变量执行以下操作:
- 设置默认文本编辑器或浏览器。
- 更改可执行文件的路径。
- 设置系统区域设置和键盘布局。
- 存储机密令牌或密码。
在 Linux 中,环境变量可以影响应用程序的运行方式,例如,可以修改应用程序的输入和输出路径,控制程序的执行环境等。许多 Linux 发行版都会提供工具来帮助用户配置环境变量,例如:“export”命令和“set”命令等。
对于普通用户而言,环境变量通常只对单个应用程序产生影响,例如:“JAVA_HOME”变量可以影响 Java 程序的执行环境。而对于系统管理员而言,他们可以配置环境变量以影响整个系统的行为,例如:“PATH”环境变量可以指定系统命令查找的路径。
命名行参数
argc与argv
且看下面代码分析:
//myproc.c
1 #include <stdio.h>
2
3 int main(int argc, char* argv[])
4 {
5 for(int i=0;i<argc;i++)
6 {
7 printf("argv[%d]->%s\n",i,argv[i]);
8 }
9 return 0;
10 }
上面程序执行,我们在命名行上输入的东西逐渐变多,这个数组打印的东西也变多
所谓的命令行参数其实需要将程序名与选项依次传递给 argv 的
我们改进一下代码,跟别的指令(ls等)一样,通过输入不同的选项,运行不同的功能:
//myproc.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[], char* env[])
{
if (argc != 2)
{
printf("Usage: \n\t%s [-a/-b/-c/-ab/-bc/-ac/-abc]\n", argv[0]);
return 1;
}
if (strcmp("-a", argv[1]) == 0)
{
printf("功能a\n");
}
if (strcmp("-b", argv[1]) == 0)
{
printf("功能b\n");
}
if (strcmp("-c", argv[1]) == 0)
{
printf("功能c\n");
}
if (strcmp("-ab", argv[1]) == 0)
{
printf("功能ab\n");
}
if (strcmp("-bc", argv[1]) == 0)
{
printf("功能bc\n");
}
return 0;
}
执行结果:
env
另外一个参数env:
1 #include <stdio.h>
2 #include <string.h>
3
4 int main(int argc,char* argv[],char* env[])
5 {
6 for(int i=0;env[i];i++)//环境变量最后以NULL结尾
7 {
8 printf("env[%d]:%s\n",i,env[i]);
9 }
10 return 0;
11 }
其实env就是一个指针数组,里面指向由环境变量形成的长字符串,这里的代码就是打印所有环境变量
我们可以通过增加一个环境变量来验证一下:
可以发现,我们增加一个环境变量,然后运行mypro程序,出现了这个环境变量。
environ
我们在使用main函数的时候可以不传递参数,使用environ指针
1 #include <stdio.h>
2 #include <string.h>
3
4 //int main(int argc,char* argv[],char* env[])
5 int main()
6 {
7 extern char** environ;
8 for(int i=0;environ[i];i++)
9 {
10 //printf("env[%d]:%s\n",i,env[i]);
11 printf("environ[%d]:%s\n",i,environ[i]);
12 }
13 return 0;
14 }
作用跟char * env[ ]是一样的
在进程上下文中,获取环境变量的三种方式:
- getenv
- char* env[ ]
- extern char** environ
如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀