【Linux】环境变量完全解析
9.环境变量
文章目录
- 9.环境变量
- 一、命令行参数
- 二、获取环境变量
- 程序中获取环境变量
- 1. 使用命令行参数
- 2. 使用系统调用函数`getenv("字符串");`
- 3. 使用系统提供的全局变量`environ`
- 命令行中查询环境变量
- 三、常见环境变量
- 1. HOME
- 2. OLDPWD
- 3. PATH
- 4. SHELL
- 四、环境变量与本地变量
- 本地变量与环境变量的对比
- 本地变量修改为环境变量
- 五、总结
一、命令行参数
在Linux中,命令行参数用于向程序传递信息。这些参数可以在命令行中指定,并由程序解析和使用。
Linux中的指令其实也是一个可执行程序,Linux下一切皆文件,在使用Linux的某一些指令的时候,后面经常会带有选项,这个选项就是命令行参数。
举例:我们在终端中执行以下代码
#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{printf("argc: %d\n", argc);for(int i = 0; i < argc; i++){printf("argv[%d]: %s\n", i, argv[i]);}return 0;
}
执行结果:
[lisihan@hcss-ecs-b735 lession13]$ make
gcc -o code code.c -std=c99
[lisihan@hcss-ecs-b735 lession13]$ ./code
argc: 1
argv[0]: ./code
[lisihan@hcss-ecs-b735 lession13]$ ./code 1 2 3 4 5
argc: 6
argv[0]: ./code
argv[1]: 1
argv[2]: 2
argv[3]: 3
argv[4]: 4
argv[5]: 5
[lisihan@hcss-ecs-b735 lession13]$ ./code aaa bbb ccc ddd
argc: 5
argv[0]: ./code
argv[1]: aaa
argv[2]: bbb
argv[3]: ccc
argv[4]: ddd
可以看到在执行code的时候后面可以带参数,并且这个参数可以由main函数传参之后再code中打印出来。
-
这里把main函数的这个参数,把它我们称之为叫做命令行参数列表,其中argc表示的是参数的个数,argv表示的是我们是一个数组,它表示的是参数的清单。
-
同一个程序,可以根据命令行参数,根据选项的不同,表现出不同的功能。比如:指令中选项的实现!
-
在Linux系统中,用户在命令行界面输入的指令本质上是字符串序列。命令行解释器(Shell)首先接收这些字符串,并依据空格作为分隔符对其进行解析分割。Shell自身是一个运行中的进程,当它执行用户指定的程序时,该程序会作为Shell的子进程启动。如前所述,进程具有独立性。父子进程会继承父进程的代码段;对于数据段,原则上需保持各自私有。然而,若父子进程仅读取而不修改某个全局变量(即该数据处于只读状态),则无需为双方创建独立的副本。具体实现机制后续详述。因此,Shell进程与通过命令行启动的用户程序(包括用户自定义程序)之间,构成父子进程关系。
二、获取环境变量
程序中获取环境变量
1. 使用命令行参数
其实在main函数中不止有两个参数,还有第三个参数用于配置环境变量,char *env[]
,同样他也是一个char*类型的指针数组。通过下面代码来做具体解释:
#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[], char *env[])
{for(int i = 0; env[i]; i++)//如果env[i]为0则后面没有数据了,这是系统规定,相当于字符串后面加上一个`\0`printf("env[%d]: %s\n", i, env[i]);return 0;
}
执行结果:
[lisihan@hcss-ecs-b735 lession13]$ make
gcc -o code code.c -std=c99
[lisihan@hcss-ecs-b735 lession13]$ ./code
env[0]: XDG_SESSION_ID=150
env[1]: HOSTNAME=hcss-ecs-b735
env[2]: TERM=xterm
env[3]: SHELL=/bin/bash
env[4]: HISTSIZE=10000
env[5]: SSH_CLIENT=218.77.77.250 39505 22
env[6]: SSH_TTY=/dev/pts/1
env[7]: USER=lisihan #用户
env[8]: LD_LIBRARY_PATH=:/home/lisihan/.VimForCpp/vim/bundle/YCM.so/el7.x86_64
env[9]: LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36: #当前配色方案
env[10]: MAIL=/var/spool/mail/lisihan
env[11]: PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisihan/.local/bin:/home/lisihan/bin
env[12]: PWD=/home/lisihan/lession13 #pwd,当前位置
env[13]: LANG=en_US.UTF-8
env[14]: HISTCONTROL=ignoredups
env[15]: SHLVL=1
env[16]: HOME=/home/lisihan
env[17]: LOGNAME=lisihan
env[18]: SSH_CONNECTION=218.77.77.250 39505 192.168.3.169 22
env[19]: LESSOPEN=||/usr/bin/lesspipe.sh %s
env[20]: XDG_RUNTIME_DIR=/run/user/1000
env[21]: HISTTIMEFORMAT=%F %T lisihan
env[22]: _=./code
env[23]: OLDPWD=/home/lisihan
-
每个程序都会收到⼀张环境表,环境表是⼀个字符指针数组,每个指针指向⼀个以’\0’结尾的环境字符串
-
从结果中我们可以看出:打印出来的结果就是当前这个程序的换件变量配置,所有环境变量最终格式都是
key = value
的格式 -
环境变量通常具有全局属性,可以被⼦进程继承下去 。在进程创建时,操作系统会将父进程的环境变量表副本传递给新进程。无论该进程作为子进程、兄弟进程或其他派生关系存在,每个进程均通过继承机制获取其父进程的环境变量表,并维护独立的实例。
2. 使用系统调用函数getenv("字符串");
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>int main()
{printf("USER: %s\n", getenv("USER"));printf("HOME: %s\n", getenv("HOME"));printf("PWD: %s\n", getenv("PWD"));printf("PATH: %s\n", getenv("PATH"));return 0;
}
运行结果:
[lisihan@hcss-ecs-b735 lession13]$ ./code1
USER: lisihan
HOME: /home/lisihan
PWD: /home/lisihan/lession13
PATH: /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisihan/.local/bin:/home/lisihan/bin:/home/lisihan/lession13
3. 使用系统提供的全局变量environ
这是我们C语言提供的一个标准全局变量,也称为环境变量的前半部分。它是一个char类型的指针,因为环境变量表示字符数组,所以要指向环境变量的第一个元素,其类型必须是char* 。由于bash是用C语言编写的,它还会在内部维护一个char*类型的指针environ,该指针指向当前对应的环境变量表。因此,如果我们想获取环境变量,既不想通过getenv函数获取,也不想通过其他参数获取,系统中本来就存在environ变量,我们可以将其视为数组,并直接输出environ中对应的元素。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>extern char **environ;int main()
{for(int i = 0; environ[i]; i++)printf("%s\n", environ[i]);return 0;
}
运行结果:
[lisihan@hcss-ecs-b735 lession13]$ gcc -o code2 code2.c -std=c99
[lisihan@hcss-ecs-b735 lession13]$ ./code2
XDG_SESSION_ID=161
HOSTNAME=hcss-ecs-b735
TERM=xterm
SHELL=/bin/bash
#
#与前面是一样的,这里就不显示了
#
HOME=/home/lisihan
SHLVL=4
LOGNAME=lisihan
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
HISTTIMEFORMAT=%F %T lisihan
_=./code2
命令行中查询环境变量
环境变量不是凭空产生的,我们可以在命令行中用指令env
查看当前位置的环境变量:
[lisihan@hcss-ecs-b735 lession13]$ env
XDG_SESSION_ID=150
HOSTNAME=hcss-ecs-b735
TERM=xterm
SHELL=/bin/bash
#
#与前面是一样的,这里就不显示了
#
LOGNAME=lisihan
SSH_CONNECTION=218.77.77.250 39505 192.168.3.169 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
HISTTIMEFORMAT=%F %T lisihan
_=/usr/bin/env
OLDPWD=/home/lisihan
需要注意的是:不同路径下环境变量其实是不一样的,我们从PWD中就可以看出
小细节:
使用su -
切换为root用户之后,环境变量中的USER和LOGNAME会相应的变为root
[lisihan@hcss-ecs-b735 lession13]$ env
#有一些我删了,只保留有用的数据
USER=lisihan
MAIL=/var/spool/mail/lisihan
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisihan/.local/bin:/home/lisihan/bin:/home/lisihan/lession13
PWD=/home/lisihan/lession13
HOME=/home/lisihan
LOGNAME=lisihan[lisihan@hcss-ecs-b735 lession13]$ su -
Password:
Last login: Sat May 24 09:13:52 CST 2025 from 218.77.77.250 on pts/1
Last failed login: Fri May 30 14:28:53 CST 2025 from 14.103.117.98 on ssh:notty
There were 6266 failed login attempts since the last successful login.
[root@hcss-ecs-b735 ~]# env
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
但是如果我们用su
直接以root身份进行操作但不登录root,USER和LOGNAME不会变为root
[lisihan@hcss-ecs-b735 ~]$ env
USER=lisihan
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/home/lisihan
HOME=/home/lisihan
LOGNAME=lisihan
[lisihan@hcss-ecs-b735 ~]$ su
Password:
[root@hcss-ecs-b735 lisihan]# env
USER=lisihan
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/home/lisihan
HOME=/root
LOGNAME=lisihan
[root@hcss-ecs-b735 lisihan]# cd ~
[root@hcss-ecs-b735 ~]# env
USER=lisihan
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=lisihan
三、常见环境变量
1. HOME
-
在Linux系统中,环境变量
HOME
存储着当前用户的家目录路径,可通过echo $HOME
命令查看其值。 -
HOME的作用:当使用
su
命令切换用户身份时(如切换至root用户),该变量值会动态更新为相应用户的家目录路径,因为不同用户拥有独立的家目录配置。关于登录初始化流程:用户认证成功后,系统会启动Shell进程(如Bash),该进程首先从配置文件中加载环境变量(包括HOME
),随后依据HOME
的值将进程的初始工作位置设定为家目录。这一顺序表明:环境变量的加载发生在工作目录设定之前,家目录位置本质上是由HOME
变量所决定的。 -
修改当前工作路径:==更改当前工作目录可通过Bash进程调用
chdir
系统函数实现,该操作会更新进程的工作位置。==由于Bash作为用户交互接口,其工作目录决定用户默认所处位置。需注意:所有命令行启动的进程均为Bash的子进程,在创建时会继承父进程的工作目录属性——这是通过复制PCB实现的。当在Bash中切换路径后,其工作目录更新,后续创建的子进程将继承此新路径。穿插一个小知识点:
登录时的默认家目录设定即基于此机制:Bash启动后首先读取
HOME
环境变量(该变量由系统根据用户名自动设置,如普通用户为/home/用户名
,root用户为/root
),再通过chdir
切换至该路径。另存在PWD
环境变量动态记录当前工作路径,其更新与目录切换同步,主要作用是向运行中的程序提供位置信息。程序可通过标准库函数(如getcwd
)获取此值。
2. OLDPWD
你的Linux系统环境变量中有一个叫做oldpwd,它总会保存你最近一次所在的路径。所以cd内部只要识别到你的选项是,就会直接获取oldpwd,然后改变当前进程路径。这就是为什么它能来回跳转的原因,每个环境变量在系统层面上都有其各自的作用。
3. PATH
在之前提到过,Linux下一切皆文件,命令行中的各种命令其实就是各种可执行文件。但我们会发现,当我们使用Linux系统中自带的或yum install
下载的各种程序命令的时候,我们不需要在前面加上文件路径,比如:./
,但是当我们执行自己的可执行程序的时候,我们需要带有文件路径,比如./code
。下面对此做出解释。
-
执行系统命令无需路径前缀,而执行用户自定义程序需使用
./
显式指定当前目录路径,此差异源于可执行文件的搜索机制。进程创建需先定位可执行文件实体,系统命令如pwd
位于预定义路径(如/usr/bin
),而自定义程序code
未在搜索路径内故需显式路径。 -
其根本机制在于:Shell通过环境变量
PATH
定义的冒号分隔路径集合(如/usr/bin:/bin
)进行文件搜索,当输入命令时,Shell依次遍历PATH
中各路径直至定位可执行文件;若未命中则报错。自定义程序因当前目录(.
)通常不在PATH
中,故需./code
显式指定。 -
解决方案有二:1) 将程序复制至
PATH
包含路径(如/usr/bin
);2) 将当前目录添加至PATH
环境变量。 -
如何修改PATH
- 注意修改的时候不能直接用等号赋值,应该要在之前的
$PATH
中的内容后面添加PATH=$PATH:<新路径>
,注意不同的路径之间要用:
分开 - 目前继承的环境变量全都是内存级的,不用担心改错环境变量。因为只要关闭当前shell,重新登录,再形成新的shell,path就会自动恢复。
- 环境变量的初始值源于系统配置文件,其加载机制遵循严格流程:用户登录时启动的Shell进程会解析
/etc/profile
及家目录下的**.bashrc
,.bash_profile
**等配置文件,将其内容载入内存构建环境变量表。该表通过进程继承机制传递给所有派生进程(如命令行执行的程序)。环境变量的持久化修改需编辑对应配置文件,例如在.bash_profile
中添加PATH=$PATH:/custom/path
并执行source .bash_profile
使变更生效。进程的用户标识(UID)同样继承自登录会话——系统通过PAM(Pluggable Authentication Modules)认证后,将用户凭证植入初始Shell的环境变量(如USER
),后续进程据此继承身份属性。此机制确保文件权限校验时,进程UID能与文件UID进行所有权匹配。
- 注意修改的时候不能直接用等号赋值,应该要在之前的
[lisihan@hcss-ecs-b735 lession13]$ ls
code code.c Makefile
[lisihan@hcss-ecs-b735 lession13]$ pwd
/home/lisihan/lession13
[lisihan@hcss-ecs-b735 lession13]$ echo $PATH
-bash: /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisihan/.local/bin:/home/lisihan/bin:
[lisihan@hcss-ecs-b735 lession13]$ PATH=$PATH:/home/lisihan/lession13
[lisihan@hcss-ecs-b735 lession13]$ echo $PATH
-bash: /usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/lisihan/.local/bin:/home/lisihan/bin:/home/lisihan/lession13:
4. SHELL
SHELL : 当前Shell,它的值通常是/bin/bash
四、环境变量与本地变量
在shell命令行中我们可以执行类似代码一样的脚本语句,并且可以用echo $<变量>
,来查看在命令行中定义的变量
[lisihan@hcss-ecs-b735 lession13]$ i=0; for((;i<10;i++)); do echo $i; done
0
1
2
3
4
5
6
7
8
9
[lisihan@hcss-ecs-b735 lession13]$ echo $i
10
像i
这类在shell命令行中定义的变量我们称之为本地变量。
小知识:
Bash进程具备语法解析能力,可识别
while
、for
等控制结构及变量定义操作。当输入此类指令时,Bash并非简单视作字符串,而是将其解析为程序逻辑并执行相应操作。基于此解释执行能力,通过编写包含变量、循环及命令序列的文本文件(即Shell脚本),由Bash逐行解释运行,实现自动化任务处理。这种将命令解释器扩展为脚本执行引擎的机制,与Python、PHP等解释型语言的工作原理具有本质一致性——均通过运行时环境动态解析并执行源码。
本地变量与环境变量的对比
-
环境变量本质是操作系统维护的全局性键值对数据,其管理机制包含定义、验证与转换操作。在Shell中可通过
VAR=value
语法定义本地变量(如a=100
),此类变量仅存在于当前Shell进程内部,不会被env
命令显示,但可通过set
命令查看所有变量(含环境变量与本地变量)。 -
本地变量常用于Shell脚本控制(如循环计数)或界面配置(如
PS1
提示符格式)。在使用env
命令时也不会显示出来,如果要显示当前所有的环境变量与本地变量,需要用一个新的命令set
[lisihan@hcss-ecs-b735 lession13]$ set BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() BASH_LINENO=() BASH_SOURCE=() BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu") BASH_VERSION='4.2.46(2)-release' COLUMNS=210 DIRSTACK=() EUID=1000 GROUPS=() HISTCONTROL=ignoredups HISTFILE=/home/lisihan/.bash_history HISTFILESIZE=10000 HISTSIZE=10000 HISTTIMEFORMAT='%F %T lisihan ' HOME=/home/lisihan HOSTNAME=hcss-ecs-b735 HOSTTYPE=x86_64 ID=1000 IFS=$' \t\n' LANG=en_US.UTF-8 LD_LIBRARY_PATH=:/home/lisihan/.VimForCpp/vim/bundle/YCM.so/el7.x86_64 LESSOPEN='||/usr/bin/lesspipe.sh %s' LINES=43 LOGNAME=lisihan LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:' MACHTYPE=x86_64-redhat-linux-gnu MAIL=/var/spool/mail/root MAILCHECK=60 OLDPWD=/root OPTERR=1 OPTIND=1 OSTYPE=linux-gnu PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin PIPESTATUS=([0]="0") PPID=27810 PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"' PS1='[\u@\h \W]\$ ' #本地变量明当前命令行的格式、用户主机名、当前工作路径和提示符 PS2='> ' #本地变量 PS4='+ ' #本地变量 PWD=/home/lisihan/lession13 SHELL=/bin/bash SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor SHLVL=4 TERM=xterm UID=1000 USER=lisihan XDG_RUNTIME_DIR=/run/user/1000 XDG_SESSION_ID=161 _=10 colors=/home/lisihan/.dircolors i=10 #这是我们之前定义的本地变量
-
环境变量与本地变量的核心差异在于继承性:环境变量可通过进程派生机制传递给子进程,而本地变量仅限当前Shell进程访问。为验证此特性,设计程序通过
getenv("IS_RUNNING")
检测特定环境变量:若变量不存在则启动程序并标记运行状态;若存在则阻止重复启动。实验表明,当IS_RUNNING
作为本地变量时(通过VAR=value
设置),子进程无法检测到该变量;但使用export
命令将其转为环境变量后,子进程即可继承该变量并实现单实例控制。此过程同时揭示环境变量的动态管理机制:通过unset
命令可移除指定环境变量,使程序恢复可启动状态。
本地变量修改为环境变量
若需将本地变量提升为全局环境变量,需使用export
命令(如export a
),该操作实质是将变量从Shell的本地变量表迁移至环境变量表。环境变量表在进程创建时被子进程继承,而本地变量表仅限当前Shell访问。当执行echo $a
时,Shell优先检索本地变量表,未命中时再查询环境变量表。
五、总结
相关文章:

【Linux】环境变量完全解析
9.环境变量 文章目录 9.环境变量一、命令行参数二、获取环境变量程序中获取环境变量1. 使用命令行参数2. 使用系统调用函数getenv("字符串");3. 使用系统提供的全局变量environ 命令行中查询环境变量 三、常见环境变量1. HOME2. OLDPWD3. PATH4. SHELL 四、环境变量与…...
【Java】mybatis-plus乐观锁-基本使用
乐观锁(Optimistic Locking)是解决并发问题的重要机制。它通过在数据更新时验证数据版本来确保数据的一致性,从而避免并发冲突。与悲观锁不同,乐观锁并不依赖数据库的锁机制,而是通过检查数据的版本或标志字段来判断数…...

力扣每日一题——找到离给定两个节点最近的节点
目录 题目链接:2359. 找到离给定两个节点最近的节点 - 力扣(LeetCode) 题目描述 解法一:双指针路径交汇法 基本思路 关键步骤 为什么这样可行呢我请问了? 举个例子 特殊情况 Java写法: C写法&a…...
机器学习与深度学习03-逻辑回归01
目录 上集回顾1. 逻辑回归与线性回归的区别2.逻辑回归的常见目标函数3.逻辑回归如何分类4.Sigmoid函数详解5.逻辑回归模型的参数 上集回顾 上一节文章地址:链接 1. 逻辑回归与线性回归的区别 应用领域 线性回归通常⽤于解决回归问题,其中⽬标是预测⼀…...

卷积神经网络(CNN)入门学习笔记
什么是 CNN? CNN,全称 卷积神经网络(Convolutional Neural Network),是一种专门用来处理图片、语音、文本等结构化数据的神经网络。 它模仿人眼识别图像的方式: 从局部到整体,一步步提取特征&a…...
【优笔】基于STM32的多模态智能门禁系统
代码功能详细描述 该代码实现了一个基于STM32的多模态智能门禁系统,整合密码、指纹、人脸识别(预留)三种验证方式,并提供完善的管理功能。系统架构如下图所示: #mermaid-svg-Uufpcoeo5Lega096 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size…...
Metasploit工具使用详解(上)丨小白WEB安全入门笔记
Metasploit工具使用详解(上)丨小白WEB安全入门笔记 一、课程定位与工具概述 课程性质: 小白WEB安全入门课程聚焦基础操作,非深度专题(Metasploit专题可讲数十节课)目标:掌握基本概念和简单漏洞利用 Metasploit核心定…...
Femap许可证与网络安全策略
随着科技的快速发展,网络安全问题已成为各行各业关注的焦点。在电磁仿真领域,Femap作为一款领先的软件,其许可证的安全性和网络策略的重要性不言而喻。本文将探讨Femap许可证与网络安全策略的关系,确保您的电磁仿真工作能够在一个…...

VLAN的作用和原理
1. 为什么要有vlan? 分割广播域,避免广播风暴,造成网络资源的浪费 可以灵活的组网,便于管理,同时还有安全加固的功能 2. vlan是怎么实现的?端口的原理? 设置VLAN后,流量之间的转…...

深入探讨集合与数组转换方法
目录 1、Arrays.asList() 1.1、方法作用 1.2、内部实现 1.3、修改元素的影响 1.4、注意事项 2、list.toArray() 2.1、方法作用 2.2、内部实现 2.3、修改元素的影响 2.4、特殊情况 1、对象引用 2、数组copy 3、对比总结 4、常见误区与解决方案 5、实际应用建议…...
让大模型看得见自己的推理 — KnowTrace结构化知识追踪
让大模型“看得见”自己的推理 —— KnowTrace 结构化知识追踪式 RAG 全解析 一句话概括:把检索-推理“改造”成 动态知识图构建任务,再让 LLM 只关注这张不断精炼的小图 —— 这就是显式知识追踪的核心价值。 1. 背景:为什么 RAG 仍难以搞定多跳推理? 长上下文负担 传统 I…...

【HarmonyOS 5应用架构详解】深入理解应用程序包与多Module设计机制
⭐本期内容:【HarmonyOS 5应用架构详解】深入理解应用程序包与多Module设计机制 🏆系列专栏:鸿蒙HarmonyOS:探索未来智能生态新纪元 文章目录 前言应用与应用程序包应用程序的基本概念应用程序包的类型标识机制应用安装流程 应用的…...

【Oracle】DCL语言
个人主页:Guiat 归属专栏:Oracle 文章目录 1. DCL概述1.1 什么是DCL?1.2 DCL的核心功能 2. 用户管理2.1 创建用户2.2 修改用户2.3 删除用户2.4 用户信息查询 3. 权限管理3.1 系统权限3.1.1 授予系统权限3.1.2 撤销系统权限 3.2 对象权限3.2.1…...

MySQL强化关键_017_索引
目 录 一、概述 二、索引 1.主键索引 2.唯一索引 3.查看索引 4.添加索引 (1)建表时添加 (2)建表后添加 5.删除索引 三、树 1.二叉树 2.红黑树 3.B树 4.B树 (1)为什么 MySQL 选择B树作为索引…...
stm32——SPI协议
stm32——SPI协议 STM32的SPI(Serial Peripheral Interface,串行外设接口)协议是一种高速、全双工、同步的串行通信协议,广泛评估微控制器与各种外设(如传感器、器件、显示器、模块等)之间的数据传输。STM3…...
Linux 下如何查看进程的资源限制信息?
简介 Linux 上的 cat /proc/$pid/limits 命令提供有关特定进程的资源限制的信息,其中 $pid 是相关进程的进程 ID (pid)。该文件是 /proc 文件系统的一部分,该文件系统是一个虚拟文件系统,提供有关进程和系统资源的信息…...

【备忘】php命令行异步执行超长时间任务
环境说明: 操作系统:windows10 IDE:phpstorm 开发语言:php7.4 框架:thinkphp5.1 测试环境:linuxwindows均测试通过。 初级方法: function longRunningTask() {$root_path Tools::get_ro…...
对于ARM开发各种手册的分类
手册名称全称主要内容适用范围是不是讲SysTick?Cortex-M3 Technical Reference Manual (TRM)Cortex-M3 Technical Reference Manual描述 Cortex-M3内核架构,如寄存器模型、总线接口、指令集、异常模型只适合 Cortex-M3 内核,不含外设❌ 没有C…...
java开发中#和$的区别
在Spring框架中,$ 和 # 是两种不同的表达式前缀,用于从不同的来源获取值或执行计算。下面详细解释它们的区别和用法: 一、$ 占位符(Property Placeholder) 1. 作用 从配置文件(如 application.propertie…...

在 RK3588 上通过 VSCode 远程开发配置指南
在 RK3588 上通过 VSCode 远程开发配置指南 RK3588 设备本身不具备可视化编程环境,但可以通过 VSCode 的 Remote - SSH 插件 实现远程代码编写与调试。以下是完整的配置流程。 一、连接 RK3588 1. 安装 Debian 系统 先在 RK3588 上安装 Debian 操作系统。 2. 安…...

OpenHarmony标准系统-HDF框架之音频驱动开发
文章目录 引言OpenHarmony音频概述OpenHarmony音频框图HDF音频驱动框架概述HDF音频驱动框图HDF音频驱动框架分析之音频设备驱动HDF音频驱动框架分析之supportlibs实现HDF音频驱动框架分析之hdi-passthrough实现HDF音频驱动框架分析之hdi-bindev实现HDF音频驱动加载过程HDF音频驱…...

HTML Day03
Day03 0. 引言1. CSS1.1 CSS的3种使用方法1.2 内联样式1.3 内部样式表1.4 外部CSS文件 2. 图像3. 表格3.1单元格间距和单元格边框 4. 列表4.1 有序表格的不同类型4.2 不同类型的无序表格4.3 嵌套列表 5. 区块6. 布局6.1 div布局6.2 表格布局 0. 引言 HELLO ^ _ ^大家好…...

篇章六 数据结构——链表(二)
目录 1. LinkedList的模拟实现 1.1 双向链表结构图编辑 1.2 三个简单方法的实现 1.3 头插法 1.4 尾插法 1.5 中间插入 1.6 删除 key 1.7 删除所有key 1.8 clear 2.LinkedList的使用 2.1 什么是LinkedList 5.2 LinkedList的使用 1.LinkedList的构造 2. LinkedList的…...
Python60日基础学习打卡Day39
昨天我们介绍了图像数据的格式以及模型定义的过程,发现和之前结构化数据的略有不同,主要差异体现在2处 模型定义的时候需要展平图像由于数据过大,需要将数据集进行分批次处理,这往往涉及到了dataset和dataloader来规范代码的组织…...

吴恩达MCP课程(3):mcp_chatbot
原课程代码是用Anthropic写的,下面代码是用OpenAI改写的,模型则用阿里巴巴的模型做测试 .env 文件为: OPENAI_API_KEYsk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx OPENAI_API_BASEhttps://dashscope.aliyuncs.com/compatible-mode…...
MySQL访问控制与账号管理:原理、技术与最佳实践
MySQL的安全体系建立在精细的访问控制和账号管理机制上。本文基于MySQL 9.3官方文档,深入解析其核心原理、关键技术、实用技巧和行业最佳实践。 一、访问控制核心原理:双重验证机制 连接验证 (Connection Verification) 客户端发起连接时,MyS…...
AWS 创建VPC 并且添加权限控制
AWS 创建VPC 并且添加权限控制 以下是完整的从0到1在AWS中创建VPC并配置权限的步骤(包含网络配置、安全组权限和实例访问): 1. 创建VPC 步骤: 登录AWS控制台 访问 AWS VPC控制台,点击 创建VPC。 配置基础信息 名称…...
langchain学习 01
dotenv库:可以从.env文件中加载配置信息。 from dotenv import load_dotenv # 加载函数,之后调用这个函数,即可获取配置环境.env里面的内容: deep_seek_api_key<api_key>getpass库:从终端输入password性质的内…...

【清晰教程】查看和修改Git配置情况
目录 查看安装版本 查看特定配置 查看全局配置 查看本地仓库配置 设置或修改配置 查看安装版本 打开命令行工具,通过version命令检查Git版本号。 git --version 如果显示出 Git 的版本号,说明 Git 已经成功安装。 查看特定配置 如果想要查看特定…...

JAVA 常用 API 正则表达式
1 正则表达式作用 作用一:校验字符串是否满足规则作用二:在一段文本中查找满足要求的内容 2 正则表达式规则 2.1 字符类 package com.bjpowernode.test14;public class RegexDemo1 {public static void main(String[] args) {//public boolean matche…...