为什么注销后我的进程仍在运行?


10

登录后ssh,我在以下命令中输入以下命令bash

sleep 50000000000000 &

然后,我kill -9sleep流程的父流程(即bash)。然后,终端窗口同时断开。

当我再次登录时,我发现该sleep过程仍然有效。

问题:为什么sleep我退出登录并关闭终端后,该过程仍然可以生存?在我看来,nohup注销过程中除守护程序和程序外的所有内容都会被杀死。如果sleep可以通过这种方式生存下来,是否意味着我可以使用此方法代替nohup命令?


3
&会将进程派生到后台(例如守护程序),即使您已注销也可以继续运行。
Aizuddin Zali 2015年

Answers:


6

Tl; dr:

为什么sleep注销并关闭终端后该过程仍然存在?在我看来,nohup注销过程中除守护程序和程序外的所有内容都会被杀死。如果sleep可以通过这种方式生存下来,是否意味着我可以使用此方法代替nohup命令?

除非由bash产生的实例设置sshhuponexit选项,否则退出/注销后不会以任何方式终止任何进程,并且当huponexit设置了该选项时,kill -9在shell上使用替代nohup在shell的子进程上使用不是很好的选择。nohup外壳程序的子进程上的进程仍将保护它们免受不来自该外壳程序的SIGHUP的影响,即使那并不重要nohup,仍然是首选,因为它允许外壳程序正常终止。


其中bash有一个名为的选项huponexit,如果设置了该选项,它将bash在退出/注销时使SIGHUP成为其子级;

在交互式非登录 bash实例中,例如在由bash产生的实例中gnome-terminal,此选项将被忽略;无论huponexit设置还是取消设置,bash的孩子bash在退出时都不会被SIGHUPped挡住;

在交互式登录 bash实例中,例如在由bash产生的实例中ssh,不会忽略此选项(但是默认情况下未设置)。如果huponexit设置为,bashbash退出/注销时,的孩子将被SIGHUPped屏蔽;如果huponexit未设置,bashbash退出/注销后,的孩子将不会被SIGHUPped ;

因此,通常,从交互式登录bash实例退出/注销,除非huponexit设置了该选项,否则不会使shell SIGHUP成为其子代,而从交互式非登录bash实例退出/退出将不会使shell SIGHUP成为其子代而不管;

但是,在这种情况下这是无关紧要的:kill -9 sleep无论使用哪种方式都可以生存,因为杀死其父进程(bash)不会给后者留下任何对前者执行任何操作的机会(例如,如果当前bash实例是登录bash实例,并将huponexit选项设置为SIGHUP)。

此外,与其他信号(例如发送给的SIGHUP信号bash)不同,SIGKILL信号从不传播到进程的子进程,因此sleep甚至不会被杀死。

nohup启动一个不受SIGHUP信号影响的过程,这是有所不同的;它将防止进程在接收到SIGHUP信号时挂起,在这种情况bash下,如果huponexit设置了选项并且退出了shell ,则交互式登录实例可以接收到该信号;因此,从技术上讲,使用未设置选项nohup的交互式登录bash实例来启动进程huponexit将防止进程在收到SIGHUP信号后挂机,但是退出/注销shell不管如何都不会SIGHUP。

但是,总的来说,当nohup需要防止SIGHUP信号从父shell发出时,没有理由偏爱kill -9on父方法而不是nohupon子方法。相反,应该相反。

使用该kill -9方法杀死父对象不会使父对象优雅退出,而使用该nohup方法启动子对象会使父对象被其他信号终止,例如SIGHUP(在上下文中做一个有意义的例子)的孩子开始使用nohup),可以让它正常退出。


换句话说,如果我有一个放置在后台的脚本,即使我杀死了父进程,该脚本仍将在运行,例如,我的s​​hell对吗?杀死该脚本的方法是什么?
Sergiy Kolodyazhnyy 2015年

@Serg如果您有PID,只需杀死PID;如果您没有存储PID,但是可以通过其名称来标识进程,ps -e | grep process则应将过程与PID一起列出(或者,pgrep -x process如果您确定匹配单个进程而不是未拥有的事物,则更好);问题是,当您杀死一个进程时,kill -9该进程的子进程由拥有upstart,因此其原始PPID丢失,并且其PPID更改为新贵的PID,从而使其无法识别(AFAIK),但对于其名称或PID
kos 2015年

@kos在什么情况下nohup将无法防止从父进程收到SIGHUP信号后进程挂起?我正在尝试通过在后台(在PuTTY SSH shell终端中)运行一个进程nohup <command> <arg> &。当我通过单击PuTTY X按钮注销时,后台进程将立即终止。当我通过输入exitPuTTY SSH Shell终端注销时,该过程将继续在后台运行。
userpal

3

bash默认情况下,退出时不向子进程发送HUP信号。更详细(感谢@kos),它从未在非登录shell中使用

如果设置该选项,则可以将bash配置为针对登录shell执行此操作huponexit。在终端中,执行以下操作:

[romano:~] % bash -l

(这将启动一个新的“登录” shell)

romano@pern:~$ shopt -s huponexit
romano@pern:~$ sleep 1234 &
[1] 32202
romano@pern:~$ exit
logout

现在检查该sleep过程:

[romano:~] % ps augx | grep sleep
romano   32231  0.0  0.0  16000  2408 pts/11   S+   15:23   0:00 grep sleep

...未运行:它已收到HUP信号并按要求退出。


@kos ---是的,你是对的,但是...那么,如果我sleep 1000 & ; exitsleep幸存下来,那为什么呢?请注意,如果我执行kill -HUPsleep过程,它将退出。并且即使生存huponexitsleep生存。困惑...(我将尝试更好地理解并修改该asnwer,否则我将其删除)。
Rmano

2

如果sleep可以这种方式生存,是否意味着我可以使用此方法代替nohup命令?

kill -9确实不是应该走的路。这就像在电视上用枪射击时将其关闭。除了喜剧组件之外,没有任何优势。进程无法捕获或忽略SIGKILL。如果您没有给该进程完成操作和清理的机会,则可能会留下损坏的文件(或其他状态),并且无法再次启动。kill -9当别无他法时,这是最后的希望。


为什么注销并关闭终端后睡眠过程仍然可以生存?在我看来,注销时除守护程序和nohup程序以外的所有内容都将被杀死。

您遇到的情况是:

的父进程sleep是当前正在运行的bashshell。当您执行kill -9bash时,bash进程没有机会将a发送SIGHUP给其任何子进程,因为SIGKILL(由发送kill -9)由该进程捕获。睡眠过程继续运行。睡眠现在变成了一个孤儿的过程

初始化(PID 1)进程执行一种称为重命名的机制。这意味着init进程现在成为该孤立进程的父级。init是一个例外,进程可以成为它的子进程,因为它收集丢失了其原始父进程的进程。顺便说一句:sshd“进入后台” 守护程序(如)执行该操作。

如果那不会发生,那么孤立的进程将在以后(完成时)成为僵尸进程。这是什么时候waitpid()不被调用(父进程的责任,当该进程被杀死时无法履行)所发生的事情。init会waitpid()在特定的时间间隔内进行调用以避免僵尸孩子。


即使有礼貌的信号,例如TERMHUP
heemayl,2015年

@heemayl HUP取决于shell的配置:huponext。TERM将等到睡眠结束。如果是OP的睡眠命令,那将是数千年=)
混乱

1

&开始在后台的进程。如果键入ps -ef,您将看到睡眠的父进程ID(PPID)是您的重击。然后注销并再次登录。注销后,该过程将保持运行状态。第二次登录后,ps -ef再次运行。您将看到,睡眠过程的父级现在将是ID为“ 1”的进程。这就是init,即所有进程的父级。


0

使用&将导致程序在后台运行。要在后台使用bg命令查看程序,并再次使其作为前台运行,请运行fg

是的,有很多方法可以使程序即使在主终端退出时也能运行。


谢谢。bash的手册页有点令人困惑。它说:“在退出之前,交互式外壳程序将SIGHUP重新发送给所有正在运行或已停止的作业。”但实际上,该外壳程序仅将SIGHUP发送给forground作业。后台进程没有机会收到SIGHUP信号(除非更改'huponexit'shell选项)
tom_cat 2015年

@kos也许你是对的。我从这篇文章得出以上结论:stackoverflow.com/questions/4298741/… 现在,我变得更加困惑。
tom_cat

@tom_cat再次回想一下,三思而后行:根本没有情况下shell可以在运行前台进程的情况下退出,它可以是SIGHUPped之类的,但是这并没有退出。没错,它仅适用于后台进程,因为相反的做法毫无意义。但是,从进一步的研究中,也可以想到,该方法huponexit仅适用于登录外壳,例如通过的外壳ssh(而不是通过的外壳gnome-terminal
kos 2015年
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.