$ 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 章)。
一个会话是:
为作业控制目的而建立的流程组的集合。每个进程组都是一个会话的成员。进程被认为是其进程组所属的会话的成员。新创建的进程加入其创建者的会话。一个进程可以改变它的会话成员;请参阅 setid()。同一会话中可以有多个进程组。
该fork()
调用通过复制当前进程来创建一个新进程。更多信息在这篇文章中。
流程组负责人是:
进程 ID 与其进程组 ID 相同的进程。
因此,setsid
仅当它作为进程组负责人执行时才会创建一个新进程。直接在 shell 中运行命令时总是如此,因此可以将作业队列构造为进程组列表。但是,当作为脚本的一部分运行时,组长是用于运行脚本的新 shell 进程。
幸运的是,我们可以--fork
选择强制创建一个新流程。例如,shell 脚本:
#!/bin/sh
setsid --fork sleep 5
将退出而不等待sleep
完成,sleep
即使您关闭运行脚本的 shell,命令也会继续。据我所知,setsid --fork
这是正确确保命令作为分离进程运行的唯一方法。
其他资源:
您的第一个脚本等待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.
另请注意,这&
是一个控制运算符,它具有更高的优先级。希望这可以帮助!