147、【OS】【Nuttx】【周边】效果呈现方案解析:$PATH 隔离
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除
背景
上篇 blog
【OS】【Nuttx】【周边】效果呈现方案解析:VSCode Remote Server
【OS】【Nuttx】【周边】效果呈现方案解析:特殊变量$
提到了虽然不同 VSCode 终端输入的是 echo $PATH 命令,但是由于它们运行在不同的会话,所以 PATH 已经被隔离开,下面就这个点展开下
$PATH 隔离
在终端输入
cat /proc/$$/environ | tr '\0' '\n' | grep PATH
/proc/$$/environ
里面存放着当前 Shell 进程的环境变量文件
/proc/
是 Linux 的虚拟文件系统,存放运行时系统信息/proc/$$/
是 PID 为当前 Shell 进程的信息目录/proc/$$/environ
是启动时 Shell 进程的环境变量快照
注意,environ
这个文件里的环境变量是用 \0
分隔的,不是换行符 \n
,如果直接用 cat /proc/$$/environ
命令会非常难以阅读,而且 grep
命令读取输入时看到里面包含大量非文本字符 \0
,会判定这是个二进制文件,导致 grep
命令提取信息失败
所以在 grep
命令提取信息前,需要用 tr
命令预处理下,终端输入
man tr
可以看到 tr
命令描述如下
可以看到,tr
是一个用于转换(translate,tr 刚好是其缩写)或删除字符的命令:
- translate 表示把某些字符变成另一些字符,比如小写转大写,或者这里的空字符
\0
转成换行符\n
- delete 表示删除某些字符,比如删除所有空格之类的
所以这里的命令 tr '\0' '\n'
可以把环境变量 environ
之间的 \0
分隔符,替换成换行符 \n
,让每个变量独占一行
完整输入命令后,可以查看当前 Shell 进程的完整环境如下
可以看到,当前 PID 为 956657 的 Shell 进程中,PATH
变量的最前面已经添加了 vscode-server 的 remote-cli 路径
如果此时新建一个终端,再次输入上面的命令
可以看到,另一个 PID 为 964341 的 Shell 进程,其 PATH
变量的最前面也是添加了同样内容,并且 PATH
内容是一样的,但此时绝不能认为这两个 PATH
是同一个变量(虽然其内容一样)
比如在一个 PID 为 1484096 的 Shell 终端里,输入如下命令
export PATH="test_path:"$PATH
然后 echo $PATH
打印当前 Shell 的 PATH
变量
可以看到当前 Shell 的 PATH
变量里有刚才输入进去的 test_path:
然后打开一个新的 Shell 终端,PID 为 1516947,输入 echo $PATH
查看环境变量,可以看到此时是没有刚才在 PID 为 1484096 终端新增的 test_path:
内容的
从上面可以看出来,虽然两个 Shell 都有 PATH
变量,但他们是隔离的,彼此之间不会互相影响
另外,回到 PID 为 1484096 的 Shell,终端输入命令
cat /proc/$$/environ | tr '\0' '\n' | grep PATH
可以看到,虽然改变了 Shell 进程的 PATH
变量,但是在 environ
中并不会改变,这是因为之前也提到了,/proc/$$/environ
是启动时 Shell 进程的环境变量快照,不是运行时的变量值
查看官方文档 The Open Group Base Specifications Issue 7, 2018 edition 对 exec
的描述,里面有这么段描述
可以看到,execve
系统调用在进入内核后,会从提供的 envp
变量中读取环境内容,然后在新进程的内存中创建副本,这里不会修改传入的 envp
变量,相当于在启动时,存下 envp
变量当时的状态,也就是环境变量快照,所以 /proc/$$/environ
不会在运行时被修改
ok,先到这里,下篇 blog 继续