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

tom*_*cat 10 bash

通过登录后ssh,我在中键入此命令bash

sleep 50000000000000 &
Run Code Online (Sandbox Code Playgroud)

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

当我再次登录时,我发现该sleep进程还活着。

问题sleep当我注销并关闭终端时,为什么该进程可以继续存在?在我看来,除守护进程和nohup程序之外的所有内容都将在注销期间被杀死。如果sleep能这样生存下去,是不是就代表我可以用这个方法代替nohup命令了?

kos*_*kos 6

Tl;博士:

为什么sleep当我注销并关闭终端时该进程可以继续存在?在我看来,除守护进程和nohup程序之外的所有内容都将在注销期间被杀死。如果sleep能这样生存下去,是不是就代表我可以用这个方法代替nohup命令了?

除非bash生成的实例设置了sshhuponexit选项,否则在退出/注销时不会以任何方式终止任何进程,并且当huponexit设置了该选项时,kill -9在 shell 上使用不是nohup在 shell 子进程上使用的好选择;nohup在 shell 的子进程上仍然会保护它们免受不是来自 shell 的 SIGHUP 的影响,即使这并不重要nohup仍然是首选,因为它允许 shell 优雅地终止。


bash有所谓的一个选项huponexit,如果设置该将使bashSIGHUP其子女在退出/注销;

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

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

因此,通常退出/注销交互式登录bash实例,除非huponexit设置该选项,否则不会使外壳 SIGHUP 成为其子级,并且从交互式非登录bash实例退出/注销不会使外壳 SIGHUP 成为其子级不管;

然而,在这种情况下,这无关紧要: using 无论如何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需要阻止来自父 shell 的 SIGHUP 信号时,没有理由更喜欢kill -9在父方法上而不是nohup在子方法上;相反,它应该是相反的。

使用该kill -9方法杀死父级不会给父级留下优雅退出的机会,而使用该nohup方法启动子级允许父级被其他信号终止,例如 SIGHUP(在上下文中做一个有意义的例子)的孩子开始使用nohup),这允许它优雅地退出。


nob*_*ody 1

&进程在后台启动。如果输入ps -ef,您将看到 sleep 的父进程 ID (PPID) 是您的 bash。然后注销并再次登录。注销后该进程将继续运行。第二次登录后ps -ef再次运行。您将看到现在您的睡眠进程的父进程将是 ID 为“1”的进程。那就是init,所有进程的父进程。


Aiz*_*ali 0

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

是的,有很多方法可以让程序在主终端退出时保持运行。