echo: 显示某个环境变量值;echo $变量名
export: 设置一个新的环境变量;
env: 显示所有环境变量;
unset: 清除环境变量;
set: 显示本地定义的shell变量和环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。是全局变量。
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
SHELL : 当前Shell,它的值通常是/bin/bash
在linux中的命令其实都是可执行程序,要执行一个程序,必须先找到这个程序。我们写的程序要执行,一般都要通过./mytest
来运行,./
表示当前路径。
想让我们的程序直接能运行,怎么做?
1、sudo cp mytest /usr/bin/
就可以直接通过mytest执行。但是不建议这么做,因为我们的程序可能有bug,污染指令池。
2、export PATH=$PATH:新路径
,将当前路径也添加到环境变量里,export 新路径
这么写会直接覆盖系统原环境变量,只有新路径了,此时退出xshell重启即可恢复原环境变量。
通过echo $PATH
可以查看PATH环境变量,echo $HOME
查看HOME环境变量,echo $SHELL
,echo $HOSTNAME
查看主机名,echo $LOGNNAME
当前登录的用户名,echo $HISTSIZE
历史命令最大数目1000等。
如何查看环境变量?
1、命令行直接输入env
命令可以查看当前路径下的所有的环境变量。
2、getenv函数调用
#include
#include
int main()
{
char* who = getenv("USER");
printf("user:%s\n", who);
return 0;
}
通过切换yyq和root两个用户,会发现,USER环境变量也随之改变。所以得出结论:USER环境变量的最大意义是可以标识当前 使用linux的用户
由此可以将代码改为识别用户后进行操作分流
#include
#include
#include
int main()
{
char* who = getenv("USER");
if(strcmp(who, "root") == 0)
{
printf("user:%s\n", who);
}
else
{
printf("权限不足\n");
}
return 0;
}
点睛:在linux访问权限里,经常出现Permissions denied,就是因为系统通过USER来检测当前用户是否被允许访问。拥有者、所属组、others的权限就是这么来判别的。
自己在命令行定义的变量是本地变量(可以理解为c语言中的局部变量),是不能通过env查找到的,同理,getenv也无法查到。
//定义命令行变量 以及查看
[yyq@VM-8-13-centos ~]$ a=100
[yyq@VM-8-13-centos ~]$ echo $a
100
可以通过export 变量名
将shell变量变成环境变量,通过unset
清除环境变量
从进程层面来理解环境变量和shell变量
因为bash是一个系统进程,相当于是所有进程的父进程,环境变量是具有全局属性的,意味着属于bash的环境变量可以被bash的子进程继承下去;而shell变量虽然是在当前进程bash定义的,但只在bash有效。
举例:ls命令为什么能显示当前路径的文件信息呢?因为ls是个进程,继承当前bash进程的环境变量,使用了PWD,可以随时变换路径也不影响。
#include
#include
#define MYPWD "PWD"
int main()
{
char* pwd = getenv(MYPWD);
printf("%s\n", pwd);
return 0;
}
//编译得到可执行程序后,把可执行程序放到/usr/bin/路径下,就是我们自己的mypwd了
使用set
命令可以查看环境变量和shell变量。在命令行输入set
即可。
提问:main函数能带参数吗?最多有几个?–答:main函数可以带参数,最多3个。
int main(int argc, char* argv[]);
int main(int argc, char *argv[], char *env[]);
------------------
argv是指针数组,指向的是字符串
系统(startup函数)会调用main函数。
//test_argv.c
#include
int main(int argc, char* argv[])
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("argv[%d]:%s\n", i, argv[i]);
}
return 0;
}
------------------可执行程序----
[yyq@VM-8-13-centos 2023_01_03_PATH]$ ./test_argv
argv[0]->./test_argv
[yyq@VM-8-13-centos 2023_01_03_PATH]$ ./test_argv -a
argv[0]->./test_argv
argv[1]->-a
[yyq@VM-8-13-centos 2023_01_03_PATH]$ ./test_argv -a -b
argv[0]->./test_argv
argv[1]->-a
argv[2]->-b
[yyq@VM-8-13-centos 2023_01_03_PATH]$ ./test_argv -a -b -c
argv[0]->./test_argv
argv[1]->-a
argv[2]->-b
argv[3]->-c
以上可以联想到ls -l -a
,ls是可执行程序,后面跟着的是选项,其实我们所谓的命令行参数(可执行程序和选项),本质上是会依次把这些参数传给argv的,有几个argc的值就是多少,argv最后一个是NULL。
假设命令行输入"ls -a -b -c -d -e"
shell和系统在进行命令行解析的时候,需要把上面一长串字符串以空格为分割,变成"ls"
、 "-a"
、 "-b"
、 "-c"
、 "-d"
、"-e"
,那么有效字符串个数argc=6。默认argv[0]指向"ls"
,所以一个可执行程序完成不同的操作,其实就是通过argv[i]
来判断。
#include
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++){
printf("%s\n", env[i]);
}
return 0;
}
---------
env是环境变量的指针数组,最后一个是NULL。
因为环境变量也是字符串。那么环境变量也就可以其他进程拿到。
注意:env没有对应的个数,所以判断条件写为env[i]。
由此可以拿到系统/shell/bash传进来的环境变量,因为我是子进程。
通过第三方变量environ获取。因为每个程序都会收到一张环境表environ,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串 。
#include
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++){
printf("%s\n", environ[i]);
}
return 0;
}
总结:如何获取环境变量==>1、int main(int argc, char *argv[], char *env[])
;2、extern char **environ;
;3、getenv()
;4、命令行env
指令。在自己的进程上下文中获取环境变量的方法123,更推荐3。
putenv()
更改或添加环境变量–命令行export