Bash: 为什么 kill -STOP 子进程使我的子进程和当前进程在 ps 中显示相同的命令行

Bash: why kill -STOP a child process makes my child and current process to show the same command line in ps

我在脚本中有这段代码。这是一个名为 test.sh 的脚本来说明它:

#!/bin/bash
$@ &
pid=$!

#kill -STOP $pid

echo "PID = $pid"
echo '$@  = '"$@"

ps -p $pid -o uname,pid,command
echo
ps -A -o uname,pid,stat,command | grep 'script.sh' | grep -v grep

#kill -CONT $pid
wait $pid

exit 0

kill 命令被注释掉,这是故意的。发生的事情是:



    root@test# ./test.sh ./script.sh
    PID = <b>53370</b>
    $@  = ./script.sh
    USER        PID   COMMAND
    root      <b>53370</b>   <b>/bin/bash ./script.sh</b>                  <-- Child process
    
    USER      PID    STAT   COMMAND
    root      53369  S+     /bin/bash ./test.sh ./script.sh  <-- Current process
    root      <b>53370</b>  S+     <b>/bin/bash ./script.sh</b>            <-- Child process

一切正常。

现在,如果我取消注释 kill 命令,脚本会显示以下信息:



    root@test# ./test.sh ./script.sh
    PID = <b>53422</b>
    $@  = ./script.sh
    USER        PID   COMMAND
    root      <b>53422</b>   <b>/bin/bash ./test.sh ./script.sh</b>          <-- Child process
    
    USER      PID    STAT   COMMAND
    root      53421  S+     /bin/bash ./test.sh ./script.sh    <-- Current process
    root      <b>53422</b>  T+     <b>/bin/bash ./test.sh ./script.sh</b>    <-- Child process

我不确定为什么当我挂起我的子进程时,我的 当前 进程和我的 [=37] 得到完全相同的 COMMAND 值=]child 在 ps 输出中处理。

为什么会这样?我想了解这种情况下父进程和子进程之间的机制。

因为您在 fork()execve() 之间停止了 child,然后才能执行 script.sh 脚本。

kill -STOP前加一个sleep 1看看效果

A fork() 创建 child 作为 parent 进程的 copy(这意味着它将显示在 ps 输出具有相同的进程名称、命令行参数和除 pid 之外的几乎所有其他内容)。当 child 调用 execve() 系统调用时,它会替换所有这些。

fork() 之后,无法保证 parent 或 child 中的哪一个会首先 运行(事实上,他们可以 运行同时在不同的处理器上,或者它们中的任何一个都可以被无限期地抢占)——并且从它们彼此进行不同操作的顺序得出的任何“哲学”结论都是完全没有意义的;-)