bash获取后台进程id会给出父进程pid
使用以下命令创建bash脚本:bash获取后台进程id会给出父进程pid,bash,pid,Bash,Pid,使用以下命令创建bash脚本: cat <<"END"> z #! /bin/bash sleep 20 && exit 1 & ret=$! ps $ret | grep $ret END 我希望看到sleep 20…这是子进程。如果我删除&&exit 1,它将返回子进程 原因是什么?如何获取上述语句中的子进程id?您看到的不是父进程pid,而是子进程pid 运行时: sleep 20 && exit 1 & sleep
cat <<"END"> z
#! /bin/bash
sleep 20 && exit 1 &
ret=$!
ps $ret | grep $ret
END
我希望看到sleep 20…
这是子进程。如果我删除&&exit 1
,它将返回子进程
原因是什么?如何获取上述语句中的子进程id?您看到的不是父进程pid,而是子进程pid 运行时:
sleep 20 && exit 1 &
sleep 20 &
流程树类似于:
current-shell ---> sub-shell ---> 'sleep 20 && exit 1'
current-shell ---> 'sleep 20'
运行时:
sleep 20 && exit 1 &
sleep 20 &
流程树类似于:
current-shell ---> sub-shell ---> 'sleep 20 && exit 1'
current-shell ---> 'sleep 20'
为什么你会看到“睡眠20”的pid
原因是什么
原因是某些实体必须执行&&
。它不能是sleep
,因为sleep
只睡眠,在sleep
终止后(因此不再有sleep
来做出任何决定),一些“实体”需要比较sleep
的退出状态,然后决定并执行exit 1
。这个“实体”就是shell,它必须“高于”sleep
才能执行操作。所以“真实”的后台进程是shell,sleep
是它的子进程
在只有
sleep 20&
的情况下,bash中有一个优化,父shell在bash看到只有一个命令要执行的情况下会进行优化。所以bash扫描了整个命令bla bla&
,发现只有一个命令要执行。由于这个原因,bash只调用exec
,而不是标准的fork+exec
,并且变成sleep
本身,而不是运行子进程。由于exec
子shell变为sleep
,因此您可以在进程名称中看到它。这是bash完成的资源优化。您已经获得了有关子进程的正确信息。仅在您的情况下,ps
不知道或不想为您在后台启动的链接子流程显示正确的命令
名称-这可能会让您感到困惑
看起来链式命令(。&&…
)就是这种情况,因此它与出口1
也可以是echo 5
等)无关,其中名称显示为cmd
名称
从()
`cmd | COMMAND`:可执行文件的简单名称
#进程状态代码
`S`:可中断睡眠(等待事件完成)
`+`:位于前台进程组中
请参见ps | grep
输出中的S+
因此,您可以稍微调整脚本,以确认您确实捕获了(d)关于子进程的正确信息,如下所示:
cat我认为命令显示时带有父进程的名称,因为命令更复杂,无法生成名称。@dan1st well。。。这对我来说毫无意义。不管ps$ret | grep$ret如何,我实际上检查了返回pid,并与父pid和子pid进行了比较。它实际上返回父pidman bash
说和/或列表是分别由&&和| |控制运算符分隔的一个或多个管道的序列。
我看不出这对您的问题意味着什么,但我们可以同意这不会是微不足道的。谢谢您的回答。这很有帮助。我决定选择另一个更完整的答案作为你的答案。这很有帮助。我决定选择另一个更完整的答案