![shell脚本进程fork](https://linux22.com/image/110886/shell%E8%84%9A%E6%9C%AC%E8%BF%9B%E7%A8%8Bfork.png)
我正在做一些实验,以了解环境变量如何通过执行 shell 脚本从父进程继承到子进程,zsh
然后用于pstree <username>
查看继承树。
我想 zsh 会执行一个 fork 来运行脚本。但 pstree 中的进程名称是脚本文件名而不是zsh
.
#parent.sh
#! /bin/zsh
export AMA=1
./childEcho.sh #call child
#childEcho.sh
#! /bin/zsh
echo ${AMA}
./subchild.sh #call sub_child
#subchild.sh
#! /bin/zsh
echo ${AMA}
sleep 5d #sleep so that pstree can see the process tree
然后pstree
表明
sshd───zsh───parent.sh───childEcho.sh───subchild.sh───sleep
然后我删除脚本中的 hashbang 标头,再次运行,然后通过pstree
,我会得到
sshd───zsh───sh───sh───sh───sleep
所以现在进程是sh而不是脚本文件名。
- 为什么我们有这种不同的行为?
- pstree如何确定进程名称并绘制树?
- 运行时进程名称发生了变化?
答案1
程序可以更改它自己的命令行(如ps
CMD 列或中所示pstree
)。这就是 zsh 正在做的事情——它将其命令名称更改为 shell 脚本,大概是为了在查看ps
.
例如(虽然我使用的是 bash,而不是 zsh,但在 zsh 中同样有效 - 我测试过):
$ perl -E '$0 = "I AM PERL"; sleep(60);' &
[1] 504
$ ps 504
PID TTY STAT TIME COMMAND
504 pts/22 S 0:00 I AM PERL
您可以通过 获得实际的可执行文件readlink /proc/PID/exe
,至少在 Linux 上是这样。