我的命令解释器是bash shell。在我的操作系统(操作系统)上打开终端后,我执行了以下命令:
方案1
$sh -c "ps -l"
UID PID PPID TIME CMD
3038 2577 2504 00:00:00 bash
3038 2992 2577 00:00:00 ps
方案2
$sh
$ps -l
UID PID PPID TIME CMD
3038 2577 2504 00:00:00 bash
3038 3005 2577 00:00:00 sh
3038 3006 3005 00:00:00 ps
观察ps
的PID和PPID
在方案1中,我正在ps -l
shell上执行sh
命令。所以它的父亲应该是sh
,即它的PPID应该是sh
的PID。但ps -l
命令列出它的父亲是bash
。我不明白究竟发生了什么。我理解场景1 和场景2 之间的区别。但是当我在另一个操作系统(ubuntu)上执行相同的命令时,我在方案3 和方案4 中的ps -l
下获得相同的列表,如下所示:
方案3
$sh
$ps -l
UID PID PPID TIME CMD
3038 2577 2504 00:00:00 bash
3038 2991 2577 00:00:00 sh
3038 2992 2991 00:00:00 ps
方案4
$sh
$ps -l
UID PID PPID TIME CMD
3038 2577 2504 00:00:00 bash
3038 3005 2577 00:00:00 sh
3038 3006 3005 00:00:00 ps
在这两种情况下,我得到的ps
CMD的PPID为sh
的PID。到底发生了什么。我的解释错了吗?
答案 0 :(得分:2)
键入命令时,只需fork
然后按execve
命令。情景3和情景4就属于这种情况。
虽然sh -c 'ps -l'
依赖于贝壳。
在我的Linux发行版中,ls -l `which sh`
的结果是lrwxrwxrwx 1 root root 4 Oct 6 14:06 /usr/bin/sh -> bash
。
当-c
存在时,直接bash execve
以下命令。而像fish
这样的另一个shell却没有。
fish -c 'ps -l'
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 711 710 0 80 0 - 5707 wait pts/5 00:00:00 bash
0 S 1000 1519 711 0 80 0 - 7054 wait pts/5 00:00:00 fish
0 R 1000 1526 1519 0 80 0 - 9266 - pts/5 00:00:00 ps
execve
做的是用新的流程图像替换当前流程图像。fork
创建一个新流程。