3
$ cat test1.sh
#!/bin/bash

setsid sleep 100

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

$ cat test2.sh
#!/bin/bash

setsid sleep 100 &

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

谁能为我解释一下?非常感谢。

4

2 回答 2

1

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

我也对 的这种行为感到惊讶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这是正确确保命令作为分离进程运行的唯一方法

其他资源:

于 2022-01-07T01:52:44.893 回答
0

您的第一个脚本等待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.

另请注意,这&是一个控制运算符,它具有更高的优先级。希望这可以帮助!

于 2014-01-20T12:06:47.630 回答