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


11

我正在帮助一位同事,他的后台进程间歇性地死了。

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

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

我大叫“啊哈”。“如果使用“&”启动命令,则退出控制终端时它将挂断。您需要使用诸如nohup之类的方法来实现此目的。确实,此过程需要支持作为守护程序运行,tut tut。

我们测试了上面的命令以证明我的观点,并且...似乎起作用了:当我们退出运行上述命令的终端时,由命令启动的过程并未退出。

command是一个自定义Python脚本,其输出将发送到文件。据我所知,脚本中没有智能化的“守护进程”功能。它不执行在Wikipedia:守护程序(计算):创建页面中列出的作为守护程序运行所需的任何操作。

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

<command> &
exit

在上述情况下,当我们退出终端时,由命令启动的后台进程将退出。

我的问题是这样的:

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

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

我想在公司内部传播最佳做法,但是我需要能够证明和支持我提出的任何建议。

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

Answers:


12

由于终端快死了,有几种方法可以杀死进程。

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

  2. 第二种方法是,当外壳程序收到SIGHUP时,将其信号重新发送到其子进程-更确切地说,发送至其后台作业。一些外壳程序(ksh,bash,zsh)具有disown内置功能,可以告诉外壳程序不要将SIGHUP发送到特定作业。

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

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


我已经看到root用户这样做chroot --userspec root:root / sh -c "exec some_forever_process" &。作业正在以同一用户身份运行,nohup之前或disown之后没有明确显示。那么,对于这种情况,如何在学期退出时无法传递信号呢?
Toddius Zho '18

@ToddiusZho Presumable some_forever_process旨在永久运行(守护程序),因此可以防止自身从终端出口接收SIGHUP(通过在其自己的进程组中运行)。
吉尔斯(Gilles)'所以

bash / tail不能防止SIGHUP,但是仍然可以使用:```local $ ssh root @ REMOTE_HOST remote#chroot --userspec root:root / sh -c“ exec bash -c'tail -f / dev / null '“&[1] 6376 remote#ps -p $!--no-heading -o pid,uid,command -ww 6376 0 tail -f / dev / null remote#退出本地$ ssh root @ REMOTE_HOST remote#ps -p 6376 --no-heading -o pid,uid,command -WW 6376 0尾-f的/ dev / null的```
Toddius ZHO
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.