本文介绍了Linux中的环境变量的相关概念。
问题来了,为什么系统命令也是程序,但是执行它们时我们不需要带上路径,而我们自己的程序需要带上路径(例如:执行当前目录下的可执行文件test,需要用./test
,'.'是当前路径的意思,因此是执行当前路径的文件test)。
sudo cp 文件名 /usr/bin/
export PATH=$PATH:当前路径//注意分割路径使用的时':'
.bash_profile
执行一次,将环境变量放置在当前的shell中,所以一旦启动成功系统就会在内存中维护一个环境变量$PATH
。PATH:指定命令的搜索路径
HOME:指定用户的主工作路径(即,用户登录到Linux系统中的默认路径,用户的家目录)
LOGNAME:当前登录的用户名
HOSTNAME:主机名
SHELL:当前Shell,它的值通常是/bin/bash
查看环境变量的方法:
如果我们不想通过指令来获取环境变量,而是想在程序中获取环境变量,那么我们可以使用系统调用getenv
文件test1.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #define USER "USER"
4 int main()
5 {
6 char* who = getenv(USER);
7 printf("user:%s\n",who);
8 return 0;
9 }
运行结果
文件test1.c
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #define USER "USER"
5 int main()
6 {
7 char* who = getenv(USER);
8 if(strcmp(who,"root") == 0)
9 {
10 printf("user:%s\n",who);
11 }
12 else
13 {
14 printf("权限不足\n");
15 }
16 return 0;
17 }
运行结果:
这就解释了如何知道当前用户是否有权限去访问某文件。
执行指令或者访问文件时,文件(指令也是文件)上面的拥有者和所属组都会更根据当前用户的环境变量USER,去进行身份认证,判断是否拥有权限。
显示某个环境变量值
为什么用echo可以显示myval的值,但是用env不能显示该变量的值?
因为该变量不是环境变量而是本地变量,因此,图中的方式不是正确设置环境变量的方式。正确的方式应该使用export
设置一个新的环境变量
显示所有环境变量
也可以用grep 命令
,筛选出我们想看到的环境变量,如果没有就什么也不显示
清除环境变量
显示本地定义的shell变量(本地变量,类似于程序中的局部变量)和环境变量
bash是一个系统进程,而在命令行上运行./mycmd时,mycmd会变成bash的子进程。环境变量具有全局属性的根本原因是它是定义在bash中的,而父进程的全局变量会被子进程共享(即,会被子进程继承下去)。本地变量是定义在进程中的局部变量,只在当前进程(bash)中有效。
为什么子进程要继承父进程的环境变量?
答:为了不同的应用场景,例如:上面用USER实现的身份认证,有的进程需要用到这些环境变量来完成对应的任务。
显示当前路径
系统是如何得知我当前的路径在哪里?
例如:操作系统的基础指令ls
,加上文件名就可以查看文件,不用加上对应的路径,那么系统是如何得知我当前的路径呢?——PWD
该环境变量在bash中维护当前所处路径。路径发生改变时,shell会调整环境便利的值,而运行ls时在创建子进程,环境变量会被子进程继承,所以ls拿到了当前路径,因此使用ls时不需要带上当前路径。
文件test2.c
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<stdlib.h>
4 int main()
5 {
6 printf("%s\n",getenv("PWD"));
7 return 0;
8 }
运行结果:
main函数也是有参数的:argc(命令行参数的个数)、argv[](命令行参数表)、env[](环境变量表)。
main函数也是被系统进行调用的,它的参数是由系统进行传参的。
1 #include<stdio.h>
2 int main(int argc , char* argv[])
3 {
4 int i = 0;
5 for(;i < argc; ++i)
6 {
7 printf("argv[%d] -> %s\n", i, argv[i]);
8 }
9 return 0;
10 }
运行:
可以看到我们在命令行输入的参数越多,数组argv的内容也就越多。
命令行参数实际上是将程序名(文件名)和选项(-a/-b/-c等)传递给argv(指针数组,argv[0]存储的是程序名,剩下的存储的是选项),而argc表示选项的个数。
命令行参数的意义在于通过不同的选项控制不同的结果。
例子:
文件test2.c
1 #include<stdio.h>
2 int main(int argc , char* argv[])
3 {
4 int i = 0;
5 if(argc != 2)
6 {
7 printf("Usage:\n\t%s [-a/-b/-c/-ab/-ac/-bc/-abc]\n",argv[0]);
8 }
9 if(strcmp("-a",argv[1]) == 0)
10 printf("功能a\n");
11 if(strcmp("-b",argv[1]) == 0)
12 printf("功能b\n");
13 if(strcmp("-c",argv[1]) == 0)
14 printf("功能c\n");
15 if(strcmp("-ab",argv[1]) == 0)
16 printf("功能ab\n");
17 if(strcmp("-ac",argv[1]) == 0)
18 printf("功能ac\n");
19 if(strcmp("-bc",argv[1]) == 0)
20 printf("功能bc\n");
21 if(strcmp("-abc",argv[1]) == 0)
22 printf("功能abc\n");
23 return 0;
24 }
运行:
上面的getenv就是一种代码获取环境变量的方法。
char* env[]
。文件test3.c
1 #include<stdio.h>
2 int main(int argc, char* argv[], char* env[])
3 {
4 int i = 0;
5 for(;env[i]; ++i)
6 {
7 printf("env[%d] : %s\n", i, env[i]);
8 }
9 return 0;
10 }
文件test3.c
1 #include<stdio.h>
2 int main(int argc, char* argv[], char* env[])
3 {
4 extern char** environ;
5 int i = 0;
6 for(;environ[i]; ++i)
7 {
8 printf("env[%d] : %s\n", i, environ[i]);
9 }
10 return 0;
11 }
每个进程运行的时候都会有一张环境变量表,它本质是一个字符指针数组,每个指针指向一个以'\0'
为结尾的字符串。
以上就是今天要讲的内容,本文介绍了环境变量的相关概念。本文作者目前也是正在学习Linux相关的知识,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。
最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!