为什么SetSID无法从Shell脚本中退出


$ cat test1.sh
#!/bin/bash
setsid sleep 100

'test1.sh'shell脚本将立即退出。

$ cat test2.sh
#!/bin/bash
setsid sleep 100 &

'test2.sh'shell脚本将立即退出。

有人可以为我解释吗?非常感谢。

这个问题可能是这个较旧问题的重复性,那里的答案非常有用。也许应该合并这些。

我也对setsid的这种行为感到惊讶。所以我检查了男人页面:

DESCRIPTION
       setsid runs a program in a new session. The command calls fork(2) if already a
       process group leader. Otherwise, it executes a program in the current process.
       This default behavior is possible to override by the --fork option.

在这里了解一些行话。让我们检查POSIX定义列表(第3章)。

会话是:

为工作控制目的建立的过程组集合。每个过程组都是会话的成员。一个过程被认为是其过程组成员的会议的成员。一个新创建的过程加入了创作者的会话。一个过程可以改变其会话成员资格;请参阅setSid()。在同一会话中可以有多个进程组。

fork()调用通过复制当前过程创建一个新的过程。这篇文章中的更多信息。

流程组的负责人是:

一个过程ID与其流程组ID相同的过程。

因此,setsid仅在将其作为流程组领导者执行时创建一个新过程。直接在外壳中运行命令时,总是这种情况,因此可以将作业队列构造为过程组列表。但是,当作为脚本的一部分运行时,组领导者是用于运行脚本的新外壳过程。

幸运的是,我们有--fork的选项强制创建新过程。例如,shell脚本:

#!/bin/env bash
setsid --fork sleep 5

将退出而无需等待sleep完成,即使您关闭了脚本运行的外壳,sleep命令也将继续。据我所知, setsid --fork是正确确保命令作为独立过程的唯一方法。

其他资源:

  • 关于setsid的论坛讨论
  • setSID的源代码
  • 博客文章解释了与NOHUP相比的差异

您的第一个脚本等待setsid sleep 100完成然后返回(换句话说,它将在睡眠结束后返回,在这里100秒),但是第二个脚本不等待命令要完成,因为&将命令放在后台并立即返回。引用man bash

If  a  command is terminated by the control operator &, the shell executes the
command in the background in a subshell. The shell does not wait for the command
to finish, and the return status is 0.

还请注意,&是一个控制操作员,并且具有更高的优先级。希望这会有所帮助!

相关内容

  • 没有找到相关文章