进程在后台启动之前被杀死

雕文

我正在使用script.sh包含cmd在后台启动的命令的bash脚本

#!/bin/bash
…
cmd &
…

如果我打开一个终端仿真器并运行script.shcmd则会按预期在后台正确执行。也就是说,虽然script.sh已经结束,但cmd继续在后台运行,并具有PPID 1。

但是,如果我打开另一个终端仿真程序(让说的xfce4终端)从以前的一个(或在桌面会话的开始,这是我的真实使用情况下),并执行script.sh

xfce4-terminal -H -x script.sh

cmd不再正确执行:通过终止将其杀死script.sh仅使用nohup阻止它是不够的。我必须在sleep其后放置一个命令,否则,在与之分离之前会被cmd终止而被杀死script.sh

我发现,做的唯一途径cmd背景正确执行是把set -mscript.sh为什么在这种情况下有必要,而不是第一个呢?为什么两种执行方式script.sh(因此也是如此cmd之间的行为差​​异

我假设在第一种情况下,激活监视模式,就像通过输入可以看到的set -o那样script.sh

满天星

cmd应该在其中运行的进程将被SIGHUP之间信号杀死,任何包装程序或其他内容都将没有运行的机会,也不会产生任何效果。(您可以通过进行检查fork()exec()nohupstrace

而不是nohup,您应该在执行后台命令之前在父shell中设置SIGHUPSIG_IGN(忽略);否则,您应该设置(忽略)。如果信号处理程序设置为“忽略”或“默认”,则该处置将通过fork()继承exec()例子:

#! /bin/sh
trap '' HUP    # ignore SIGHUP
xclock &
trap - HUP     # back to default

或者:

#! /bin/sh
(trap '' HUP; xclock &)

如果您使用来运行此脚本xfce4-terminal -H -x script.sh,则终止,后台命令(xclock &)不会被SIGHUP发送的消息杀死script.sh

当会话负责人(script.sh在您的情况下,一个“拥有”控制终端的进程)终止时,内核将SIGHUP向其前台进程组中的所有进程发送a消息但是set -m将启用作业控制,并且以开头的命令&将被放入后台进程组,并且不会通过发出信号SIGHUP

如果未启用作业控制(非交互式脚本的默认设置),则以开头的命令&将在同一前台进程组中运行,并且通过从中重定向输入/dev/null并让其忽略 SIGINT来伪造“后台”模式SIGQUIT

进程从曾经作为前台作业运行但已经退出的脚本启动SIGHUP,因为它们的进程组(从其死去的父级继承)不再是终端上的前台进程,因此不会发出任何信号

额外说明:

xterm之间xfce4-terminal(可能还有其他基于vte的终端)之间的“保持模式”似乎有所不同前者将使pty的主端保持打开状态,而后者将在使用-e-x已退出的程序运行后将其断开,从而导致对从属端的任何写入操作均失败EIO当前台进程组中仍有进程正在运行时,它们xterm还将忽略WM_DELETE_WINDOW消息(即,它不会关闭)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章