linux命令setsid [英] linux command setsid
问题描述
我试图写一个包装,将执行一个脚本作为会议的领导者。
我对linux命令的行为混淆 setsid
。考虑这个剧本,名为 test.sh
:
I am trying to write a wrapper which will execute a script as a session leader.
I am confused by the behaviour of the linux command setsid
. Consider this script, called test.sh
:
#!/bin/bash
SID=$(ps -p $$ --no-headers -o sid)
if [ $# -ge 1 -a $$ -ne $SID ] ; then
setsid bash test.sh
echo pid=$$ ppid=$PPID sid=$SID parent
else
sleep 2
echo pid=$$ ppid=$PPID sid=$SID child
sleep 2
fi
的输出的不同取决于它是否执行来源:
The output differs depending on whether it is executed or sourced:
$ bash
$ SID=$(ps -p $$ --no-headers -o sid)
$ echo pid=$$ ppid=$PPID sid=$SID
pid=9213 ppid=9104 sid= 9104
$ ./test.sh 1 ; sleep 5
pid=9326 ppid=9324 sid= 9326 child
pid=9324 ppid=9213 sid= 9104 parent
$ . ./test.sh 1 ; sleep 5
pid=9213 ppid=9104 sid= 9104 parent
pid=9336 ppid=1 sid= 9336 child
$ echo $BASH_VERSION
4.2.8(1)-release
$ exit
exit
所以,在我看来, setsid
立即返回,当脚本来源,但在执行脚本时,等待它的孩子。
为什么一个控制终端的presence有什么用 setsid
?谢谢!
So, it seems to me that setsid
returns immediately when the script is sourced, but it waits for its child when the script is executed.
Why would the presence of a controlling tty have anything to do with setsid
? Thanks!
编辑:为了澄清我添加PID / PPID / SID到所有相关的命令报告
For clarification I added pid/ppid/sid reporting to all relevant commands.
推荐答案
<一个href=\"http://git.kernel.org/?p=utils/util-linux/util-linux.git;a=blob_plain;f=sys-utils/setsid.c;hb=HEAD\">The在 setsid
实用来源$ C $ C其实很简单。你会注意到它仅叉()
■如果它看到它的进程ID和进程组ID是相等的(也就是说,如果它看到,它是一个过程组长)MDASH;而且它从不等待()
S代表其子进程:如果叉()
s,则父进程只是立即返回。如果是的不的叉()
,那么它给)的外观等待(
ING一个孩子,但真正发生的事情是只是它的是的孩子,它的巴什这是等待()
ING(就像它总是这样)。 (当然,当它确实叉()
,猛砸不能等待()
为孩子它创建因为流程的wait()
为自己的孩子,而不是他们的孙子。)
The source code of the setsid
utility is actually very straightforward. You'll note that it only fork()
s if it sees that its process ID and process-group ID are equal (i.e., if it sees that it's a process group leader) — and that it never wait()
s for its child process: if it fork()
s, then the parent process just returns immediately. If it doesn't fork()
, then it gives the appearance of wait()
ing for a child, but really what happens is just that it is the child, and it's Bash that's wait()
ing (just as it always does). (Of course, when it really does fork()
, Bash can't wait()
for the child it creates, because processes wait()
for their children, not their grandchildren.)
所以,你所看到的行为是不同的行为的直接后果:
So the behavior that you're seeing is a direct consequence of a different behavior:
- 当您运行
。 ./test.sh
或源./test.sh
或诸如此类的东西&MDASH;或为此事,当你只是运行setsid
直接从Bash提示符&MDASH;庆典将推出setsid
用一个新的进程组ID为的作业控制宗旨,使setsid
将具有相同的进程ID作为其进程组ID(即,它是一个过程组组长),所以它叉()
并不会等待()
。 - 当您运行
./ test.sh
或的bash test.sh
或诸如此类的东西,它启动setsid
,setsid
将是相同的进程组作为正在运行它的脚本的一部分,所以它的进程ID和进程组-ID会有所不同,所以不会叉()
,所以它会给等待的外观(没有实际等待()
ING)。
- when you run
. ./test.sh
orsource ./test.sh
or whatnot — or for that matter, when you just runsetsid
directly from the Bash prompt — Bash will launchsetsid
with a new process-group-ID for job control purposes, sosetsid
will have the same process-ID as its process-group-ID (that is, it's a process group leader), so it willfork()
and won'twait()
. - when you run
./test.sh
orbash test.sh
or whatnot and it launchessetsid
,setsid
will be part of the same process group as the script that's running it, so its process-ID and process-group-ID will be different, so it won'tfork()
, so it'll give the appearance of waiting (without actuallywait()
ing).
这篇关于linux命令setsid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!