我在脚本中有这段代码。下面是一个名为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
命令被注释掉,这是有意的。发生的是:
- 我用另一个脚本作为参数启动这个脚本:
./test.sh ./script.sh
test.sh
启动./script.sh
,录制其PID
并显示信息- Infos显示子PID和对应于
./script.sh
的进程
root@test# ./test.sh ./script.sh
PID =53370
$@ = ./script.sh
USER PID COMMAND
root53370/bin/bash ./script.sh<-- Child process
USER PID STAT COMMAND
root 53369 S+ /bin/bash ./test.sh ./script.sh <-- Current process
root53370S+/bin/bash ./script.sh<-- Child process
一切正常。
现在,如果我取消对kill
命令的注释,脚本将显示以下信息:
root@test# ./test.sh ./script.sh
PID =53422
$@ = ./script.sh
USER PID COMMAND
root53422/bin/bash ./test.sh ./script.sh<-- Child process
USER PID STAT COMMAND
root 53421 S+ /bin/bash ./test.sh ./script.sh <-- Current process
root53422T+/bin/bash ./test.sh ./script.sh<-- Child process
我不知道为什么当我挂起我的子进程时,在ps
输出中,我的当前进程和子进程得到完全相同的COMMAND
值。
为什么会发生这种情况?我想了解在这种情况下父母和孩子之间的机制。
因为您已经在子级位于fork()
和execve()
之间时停止了它,然后它才能执行script.sh
脚本。
在kill -STOP
之前添加一个sleep 1
以查看效果。
fork()
将子进程创建为父进程的副本(这意味着它将以相同的进程名称、命令行参数以及除pid之外的几乎所有其他内容显示在ps
输出中(。当孩子调用execve()
系统调用时,它会替换所有这些。
在fork()
之后,不能保证父级或子级中的哪一个将首先运行(事实上,它们可以同时在单独的处理器上运行,或者它们中的任何一个都可能被无限期地抢占(;哲学的";根据他们彼此进行不同操作的顺序得出的结论完全没有意义;-(