为什么“su -c&” 似乎允许命令在后台运行而不挂起

为什么“su -c&” 似乎允许命令在后台运行而不挂起

我正在帮助一位遇到后台进程间歇性死机问题的同事。

我发现他们通过登录服务器并执行以下命令来启动后台进程:

su - <user> -c '<command>' &

“啊哈”,我惊呼道。 “如果你用“&”启动一个命令,当你退出控制终端时,它就会挂起。你需要使用类似 nohup 的东西来实现这一点。这个进程确实需要支持作为守护进程运行,啧啧啧。”

我们测试了上面的命令来证明我的观点......它似乎有效:该过程由命令当我们退出运行上述命令的终端时,并没有退出。

命令是一个自定义 Python 脚本,其输出将保存到文件中。据我所知,脚本中没有类似智能“守护进程”的功能。它不做任何作为守护进程运行所需的事情维基百科:守护进程(计算):创建页。

像这样运行命令的行为符合预期:

<command> &
exit

在上面的例子中,后台进程是由命令当我们退出终端时退出。

我的问题是这样的:

  1. 当我们添加“su - -c &”时会发生什么,它会阻止进程在终端退出时退出。我想详细了解控制终端、标准输入和输出等。

  2. 这是实现将此命令作为后台进程运行的目标的合理方法吗?如果不是,为什么不是?

我想在公司内传播最佳实践,但我需要能够展示和支持我提出的任何建议。

我也想了解到底发生了什么。

答案1

由于终端死亡,进程可能会通过多种方式被终止。

  1. 第一种方式是内核中的终端驱动发送 SIGHUP 信号控制过程终端是控制终端。在大多数情况下,控制进程是最初在终端中启动的 shell,其控制终端是其 stdin、stdout 和 stderr 连接到的终端。如果进程调用,它就会与控制终端断开连接setsid

  2. 第二种方法是,当 shell 收到 SIGHUP 时,会将该信号重新发送到其子进程——更准确地说,发送到其后台作业。某些 shell(ksh、bash、zsh)有一个disown内置命令来告诉 shell 不要向特定作业发送 SIGHUP。

  3. 如果终端消失并且程序尝试从中读取数据,则会通知它文件结束条件(或者可能是后台作业的 EIO)。如果终端消失并且程序尝试对其进行写入,则写入会返回并出现 EIO 错误。这些可能会导致程序退出。

所以su这里的变化是,(2) 通常会导致初始 shell 终止后台作业,但由于该后台进程以不同的用户身份运行,因此无法传递信号,并且后台进程会继续存在。

相关内容