如何在BASH中使用新的进程组ID在Linux上生成进程

5
请问如何在BASH Unix Shell中使用新的进程组ID生成新进程?谢谢!

可能是 linux命令setsid 的重复。 - user2845360
1个回答

6
要在新的进程组中运行命令,例如从命令提示符(即交互式)中运行 "emacs xxx.txt" 命令:
setsid emacs xxx.txt &

正如链接中描述的“linux command setsid”所述,setsid命令的行为可能会让人惊讶(在我现在使用的Linux中,man页根本没什么帮助)。因此...
如果您想从脚本中生成一个命令,并且希望该命令在脚本退出后继续运行,请将setsid加倍。
setsid setsid emacs xxx.txt

... 的原因如下:

  • 当 bash 在脚本中调用 setsid 时,setsid 会保留 bash 解释器进程的进程组 ID,因此:

    setsid emacs xxx.txt

    ... 会阻塞(详见链接的文章)。但在运行 emacs 前,它确实设置了一个新的进程组。

  • 你可以使用 '&' 将其放入后台:

    setsid emacs xxx.txt &

    ... 但这会留下竞争条件,即在 setsid 更改进程组之前,调用脚本可能已经退出(这可能会杀死子进程)。

  • 因此,我们希望等待进程组的更改发生;嵌套的 setsid 保证会分叉, 因为外部 setsid 不是进程组领导者,并且已经由外部 setsid 设置了一个新的进程组 ID

也就是说,当我们将 setsid 翻倍时,顺序如下:

  1. Bash 分叉出子进程 1,将其留在 Bash 的进程组中
  2. 子进程 1 执行 setsid
  3. 子进程 1 setsid 检测到它不是组长,因此调用 setsid 系统调用 (创建新的会话并为子进程 1 创建一个新的进程组)然后执行内部 setsid
  4. 内部 setsid 检测到它是组长,因此分叉子进程 2,子进程 1 退出
  5. 子进程 2 检测到它不是组长,因此调用 setsid 系统调用(创建 一个新会话并为子进程 2 创建一个新的进程组),然后执行 emacs

如果你想要从 脚本内部 与命令通信并等待其退出,请参阅 bash 手册中的 subprocess。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接