$ 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.
还请注意,&
是一个控制操作员,并且具有更高的优先级。希望这会有所帮助!