Shell 脚本中的后台作业

Shell 脚本中的后台作业

我有一个 shell 脚本script.sh,其中有一个在后台启动的命令cmd,即:

#!/bin/bash
cmd &

如果我打开一个终端仿真器(我试过 xfce4-terminal 和 gnome-terminal)并script.sh在其中运行,我的命令cmd就会有效执行,并在后台执行,正如预期的那样。

但是,如果我从上一个终端仿真器(或者在我的桌面会话开始时,这是我的真实用例)打开一个终端仿真器,并通过以下方式执行我的脚本

xfce4-terminal -H -x script.sh (or gnome-terminal -x script.sh)

该命令cmd不再执行。

我发现我可以通过将其放入我的脚本中来强制执行它set -m,但我不明白为什么在这种情况下它是必要的(实际上也不是充分的),而在前一个情况下则不是。事实上,如果我将一个放入set -o我的脚本中,我在两种情况下都会获得相同的输出。

有人可以向我解释这一点吗?或者告诉我在 shell 脚本中执行后台作业的正确方法吗?谢谢!


编辑:实际上,cmd在两种情况下都会执行,但在第二种情况下,它会因 的终止而立即被终止script.sh。为了防止这种情况,可以使用nohup,但这还不够,这对我来说是最奇怪的事情:还必须放置sleep 1或类似的东西,以允许进程在后台正确启动,并与父 shell 分离,否则它也会被终止。

我真的不明白这两个 shell 之间的行为差​​异,因为它们都是非交互式的,正如之前的评论所述。

答案1

如果您打开xfce4-trminalgnome-terminal(或其他终端),您的 shell 处于交互模式。每个脚本都以交互模式运行。

如果你script.sh跑过

xfce4-terminal -H -x script.sh

或者

gnome-terminal -x script.sh

或其他终端,您的shell处于非交互模式。

-i可以使用选项或标头强制脚本以交互模式运行#!/bin/bash -i。请注意,这可能会导致脚本行为不稳定或显示错误消息(即使没有错误)。

什么是set -m?它是监控模式。后台进程在单独的进程组中运行,并在完成后打印一行包含其退出状态的信息。默认情况下,此功能对于交互式 shell 启用。

什么是set -o?它将选项的当前设置以未指定的格式写入标准输出。

为什么set -o有效?

−o 选项是从 KornShell 中采用的,以满足用户需求。除了其通常友好的界面外,−o 还需要提供 vi 命令行编辑模式,而历史上的实践并没有为该模式产生单字母选项名称。(虽然可能可以发明这样的字母,但人们认识到会开发其他编辑模式,并且 −o 提供了足够的名称空间来描述此类扩展。)

历史实现在用于 −o 选项状态报告的格式上不一致。添加了不带选项参数的 +o 格式,以允许可移植地访问可以保存然后稍后使用点脚本等恢复的选项。

无论如何,set -m这是首选方式。

答案2

这个问题已在Unix Stackchange(另请参阅答案下方的其他评论)。这是一个谁向谁发送 SIGHUP 信号以及何时发送的问题。around in 的set -m / set +m替代cmd &方案script.shtrap '' HUP / trap - HUP

相关内容