$ 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
才会创建一个新的进程。当直接在shell中运行命令时,这种情况总是发生的,以便可以将作业队列构建为进程组列表。然而,当作为脚本的一部分运行时,组长是用于运行脚本的新shell进程。--fork
选项来强制创建一个新的进程。例如,shell脚本:#!/bin/env bash
setsid --fork sleep 5
将在不等待sleep
完成的情况下退出,并且即使关闭运行脚本的shell,sleep
命令也会继续执行。据我所知,setsid --fork
是确保命令作为独立进程运行的唯一方法。
其他资源:
你的第一个脚本等待setsid sleep 100
执行完毕,然后返回(换句话说,在sleep完成后返回,这里是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.
&
是一个控制运算符,它具有更高的优先级。希望这能帮到你!
&
将命令放入后台,导致后续命令退出。 - devnullsetsid
命令无关。 - chepner