linux命令setsid [英] linux command setsid

查看:190
本文介绍了linux命令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 or source ./test.sh or whatnot — or for that matter, when you just run setsid directly from the Bash prompt — Bash will launch setsid with a new process-group-ID for job control purposes, so setsid will have the same process-ID as its process-group-ID (that is, it's a process group leader), so it will fork() and won't wait().
  • when you run ./test.sh or bash test.sh or whatnot and it launches setsid, 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't fork(), so it'll give the appearance of waiting (without actually wait()ing).

这篇关于linux命令setsid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆