有人可以详细解释“set -m”的作用吗?

lai*_*e9m 26 linux job-control

手册页上,它只是说:

-m 作业控制已启用。

但这实际上意味着什么?

我在一个SO 问题中遇到了这个命令,我遇到了与 OP 相同的问题,即“fabric 无法启动 tomcat”。并set -m解决了这个问题。OP解释了一点,但我不太明白:

问题出在后台任务中,因为它们将在命令结束时被终止。

解决方案很简单:只需添加“set -m;” 命令前的前缀。

dha*_*hag 18

引用 bash 文档(来自man bash):

JOB CONTROL
       Job  control  refers to  the  ability  to selectively  stop
       (suspend) the execution of  processes and continue (resume)
       their execution at a later point.  A user typically employs
       this facility via an interactive interface supplied jointly
       by the operating system kernel's terminal driver and bash.
Run Code Online (Sandbox Code Playgroud)

因此,很简单地说,拥有set -m(交互式 shell 的默认设置)允许使用诸如fgand 之类的内置函数bg,这将在set +m(非交互式 shell 的默认设置)下被禁用。

然而,我不清楚作业控制和退出时终止后台进程之间的联系是什么,但我可以确认有一个:set -m; (sleep 10 ; touch control-on) &如果在键入该命令后立即退出 shell ,则运行将创建文件,但set +m; (sleep 10 ; touch control-off) &不会。

我认为答案在于以下文档的其余部分set -m

-m      Monitor  mode. [...]                     Background pro?
        cesses run in a separate process group and a  line  con?
        taining  their exit status is printed upon their comple?
        tion.
Run Code Online (Sandbox Code Playgroud)

这意味着在其下启动的后台作业set +m不是实际的“后台进程”(“后台进程是那些进程组 ID 与终端不同的进程”):它们与启动它们的 shell 共享相同的进程组 ID,而不是拥有自己的进程组 ID进程组喜欢适当的后台进程。这解释了当 shell 在它的一些后台作业之前退出时观察到的行为:如果我理解正确,当退出时,一个信号被发送到与 shell 相同的进程组中的进程(从而终止在 下启动的后台作业set +m),但不是到其他进程组的进程组(因此不考虑在 下启动的真正后台进程set -m)。

因此,在您的情况下,startup.sh脚本可能会启动后台作业。当此脚本以非交互方式运行时,例如在您链接的问题中通过 SSH 运行时,作业控制被禁用,“后台”作业共享远程 shell 的进程组,因此在该 shell 退出时立即终止。相反,通过在该 shell 中启用作业控制,后台作业获得自己的进程组,并且在其父 shell 退出时不会被终止。