目录
一、什么是环境变量
二、常见的环境变量有哪些
三、环境变量常见的指令
四、环境变量的基本布局
五、如何获取环境变量
1、通过代码获取环境变量
2、通过系统调用getenv获取
六、环境变量具有全局属性
七、main函数的命令行参数
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数
问题引入:
为什么系统命令可以直接运行,我自己写的程序必须带路径,如果不带路径,可以让自己写的程序程序和普通命令一样运行自己的程序吗?例如能够像指向系统命令pwd一样执行myproc程序
因为OS运行一个命令要先找到它,不带路径就无法找到,OS的命令默认是可被找到的,这些命令在echo $PATH中(加$可以看到环境变量PATH里的内容),pwd命令在环境变量里的/usr/bin路径中,所以pwd可以被找到,而我们的程序并不在环境变量里的路径中。
环境变量里面维护了大量的路径,而这些路径是我们搜索命令时的搜索路径,pwd它所在的路径在搜索命令的搜索路径中,因此也就解释了自己的程序不能运行,是因为当前的路径并不在环境变量所维护的众多冒号分隔的众多路径中。
可否实现自己的程序能够像pwd命令一样不带路径就能直接运行?
答案是肯定的,
方法一:把自己的exe可执行程序拷贝到搜索路径下就可以实现,这个行为是安装,但这样可能会污染其它命令,包括自己写的也可能存在bug。
方法二:我们可以新增一个环境变量,将当前路径放入到环境变量当中
[hx@VM-24-7-centos 20231201-环境变量]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[hx@VM-24-7-centos 20231201-环境变量]$ pwd
/home/hx/linux_code/20231201-环境变量
[hx@VM-24-7-centos 20231201-环境变量]$ export PATH=$PATH:/home/hx/linux_code/20231201-环境变量
[hx@VM-24-7-centos 20231201-环境变量]$ echo $PATH
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/home/hx/linux_code/20231201-环境变量
[hx@VM-24-7-centos 20231201-环境变量]$ ls
Makefile myproc myproc.c
[hx@VM-24-7-centos 20231201-环境变量]$ myproc
pid: 6873,getpid: 5275
pid: 6873,getpid: 5275
pid: 6873,getpid: 5275
^C
[hx@VM-24-7-centos 20231201-环境变量]$
PATH:指定命令的搜索路径
[hx@VM-24-7-centos 20231201-环境变量]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hx/.local/bin:/home/hx/bin
HOME:指定用户的主工作目录-用户登录到Linux系统中的默认目录
//当前用户对应的家目录
//随着用户不同,环境变量的值会根据不同的用户来决定不同变量的内容,与登录用户有关
[hx@VM-24-7-centos 20231201-环境变量]$ echo $HOME
/home/hx
[root@VM-24-7-centos ~]# echo $HOME
/root
SHELL:当前shell,通常是/bin/bash
[hx@VM-24-7-centos 20231201-环境变量]$ echo $SHELL
/bin/bash
1、echo:显示某个环境变量值
2、export:设置一个新的环境变量
导出的环境变量仅仅只在你的父bash当中设置好的变量,可以被子进程继承,导出的环境变量OS不认识,bash的环境变量从操作系统中获得
命令行中改环境变量,只在本次登录中有效
3、env:显示所有环境变量(只显示与环境相关的变量)
[hx@VM-24-7-centos 20231201-环境变量]$ env
XDG_SESSION_ID=730719
HOSTNAME=VM-24-7-centos //主机名
TERM=xterm
SHELL=/bin/bash
HISTSIZE=3000 //记住的历史命令是30000 history | wc -l
SSH_CLIENT=.................. //客户端地址
SSH_TTY=/dev/pts/0
USER=hx //用户
LD_LIBRARY_PATH=:/home/hx/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
........................
MAIL=/var/spool/mail/hx
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hx/.local/bin:/home/hx/bin
PWD=/home/hx/linux_code/20231201-环境变量
LANG=en_US.UTF-8
SHLVL=1
HOME=/home/hx
LOGNAME=hx //登录用户名
SSH_CONNECTION=..................
LESSOPEN=||/usr/bin/lesspipe.sh %s
PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
XDG_RUNTIME_DIR=/run/user/1001
HISTTIMEFORMAT=%F %T
_=/usr/bin/env
OLDPWD=/home/hx/linux_code
4、unset:清除环境变量
5、set:显示本地定义的shell变量和环境变量
显示所有的环境变量和系统私有变量的全部显示出来
[hx@VM-24-7-centos 20231201-环境变量]$ hello=你好
[hx@VM-24-7-centos 20231201-环境变量]$ echo $hello
你好
[hx@VM-24-7-centos 20231201-环境变量]$ env | grep hello
[hx@VM-24-7-centos 20231201-环境变量]$
[hx@VM-24-7-centos 20231201-环境变量]$ set | grep hello
hello=你好
//hello并不是环境变量,虽然在bash的上下文中,但是env找不到
//调用set命令
//显示bash登录所有的环境变量
//总结
//命令行上一般能定义两种类型的变量
//类似 hello=你好 的局部变量
//类似 export myenv=123 定义全局变量或环境变量
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以‘\0‘结尾的环境字符串。都是以指针数组的形式维护起来,然后以指针数组的形式以参数的方式传递给main函数
<1>、通过命令行第三个参数
#include
//char* env[]是环境变量参数,是一个指针数组
//是每一个进程在启动的时候,启动该进程的进程传递给该进程的环境变量信息
//都可以以该参数传导进来
//argc char* argv[]是命令行参数
//测试目的:获取该进程运行时的环境变量(系统传给该进程的环境变量)
int main(int argc,char* argv[],char* env[])
{
//遍历这个数组 该数组里的元素基本上都是指向环境字符串的起始地址
//最后以NULL结尾 env[i]索引对应的值
printf("begin--------------------------\n");
for(int i=0;env[i];i++)
{
printf("env[%d]:%s\n",i,env[i]);
}
printf("end----------------------------\n");
}
[hx@VM-24-7-centos 20231201-环境变量]$ ./mygetenv
begin--------------------------
env[0]:XDG_SESSION_ID=730823
env[1]:HOSTNAME=VM-24-7-centos
env[2]:TERM=xterm
env[3]:SHELL=/bin/bash
env[4]:HISTSIZE=3000
env[5]:SSH_CLIENT=58.17.9.62 53065 22
env[6]:SSH_TTY=/dev/pts/0
env[7]:USER=hx
env[8]:LD_LIBRARY_PATH=:/home/hx/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
env[9]:...............................
env[10]:MAIL=/var/spool/mail/hx
env[11]:PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/hx/.local/bin:/home/hx/bin
env[12]:PWD=/home/hx/linux_code/20231201-环境变量
env[13]:LANG=en_US.UTF-8
env[14]:SHLVL=1
env[15]:HOME=/home/hx
env[16]:LOGNAME=hx
env[17]:SSH_CONNECTION=58.17.9.62 53065 10.0.24.7 22
env[18]:LESSOPEN=||/usr/bin/lesspipe.sh %s
env[19]:PROMPT_COMMAND=history -a; history -a; printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"
env[20]:XDG_RUNTIME_DIR=/run/user/1001
env[21]:HISTTIMEFORMAT=%F %T
env[22]:OLDPWD=/home/hx/linux_code
env[23]:_=./mygetenv
end----------------------------
<2>、通过第三方变量environ获取
C/C++默认有environ全局变量,系统会给我们提供全局的第三方变量,可以帮助我们获取所有的环境变量
//man手册查看该全局变量
#include
extern char **environ;
#include
#include
//char* env[]是环境变量参数,是一个指针数组
//是每一个进程在启动的时候,启动该进程的进程传递给该进程的环境变量信息
//都可以以该参数传导进来
//argc char* argv[]是命令行参数
//测试目的:获取该进程运行时的环境变量(系统传给该进程的环境变量)
int main(int argc,char* argv[],char* env[])
{
printf("begin--------------------------\n");
extern char** environ;
for(int i=0;environ[i];i++)
{
printf("environ[%d]:%s\n",i,environ[i]);
}
printf("end----------------------------\n");
}
根据环境变量名,找到环境变量里的内容,最常用获取环境变量的接口
#include
#include
int main()
{
printf("%s\n",getenv("PATH"));
}
导出的环境变量仅仅只在你的父bash当中设置好的变量,可以被子进程继承,导出的环境变量OS不认识,bash的环境变量从操作系统中获得。
[hx@VM-24-7-centos 20231201-环境变量]$ export myenv=123
[hx@VM-24-7-centos 20231201-环境变量]$ env | grep myenv
myenv=123
///
#include
#include
#include
int main(int argc,char* argv[],char* env[])
{
printf("begin--------------------------\n");
printf("%s\n",getenv("myenv"));
printf("end----------------------------\n");
}
///
[hx@VM-24-7-centos 20231201-环境变量]$ ./mygetenv
begin--------------------------
123
end----------------------------
该代码证明两件事情
1、子进程的环境变量是从父进程中来的
2、默认所有的还款变量,都会被子进程继承,说明了环境变量具有全局属性,本质可以被所有子进程继承,所有子进程都可以拿到环境变量
1、为什么会存在命令行参数?
最大的意义,可以让同样的一个程序通过选项的方式选择使用同一个程序的不同子功能。
命令当中后面带的选项底层用的都是命令行参数完成的,命令行上的命令行参数是由父进程bash先拿到,并且传给子进程,所以子进程可以拿到命令行参数,
1 #include
2 #include
3 #include
4 #include
//argc决定argv[ ]有多少个元素
int main(int argc,char* argv[],char* env[])
15 {
41 if(argc!=2)
42 {
43 printf("Usage: %s 至少要有一个选项\n",argv[0]);
44 return 1;
45 }
46 if(strcmp("-a",argv[1])==0)
47 {
48 printf("这是功能一\n");
49 }
50 else if(strcmp("-b",argv[1])==0)
51 {
52 printf("这是功能二\n");
53 }
55 }
[hx@VM-24-7-centos 20231201-环境变量]$ ./mygetenv
Usage: ./mygetenv 至少要有一个选项
[hx@VM-24-7-centos 20231201-环境变量]$ ./mygetenv -a
这是功能一
[hx@VM-24-7-centos 20231201-环境变量]$ ./mygetenv -b
这是功能二
[hx@VM-24-7-centos 20231201-环境变量]$