通过登录后ssh
,我在中键入此命令bash
:
sleep 50000000000000 &
Run Code Online (Sandbox Code Playgroud)
然后,我kill -9
的sleep
进程的父进程(即bash
)。然后终端窗口同时断开连接。
当我再次登录时,我发现该sleep
进程还活着。
问题:sleep
当我注销并关闭终端时,为什么该进程可以继续存在?在我看来,除守护进程和nohup
程序之外的所有内容都将在注销期间被杀死。如果sleep
能这样生存下去,是不是就代表我可以用这个方法代替nohup
命令了?
为什么
sleep
当我注销并关闭终端时该进程可以继续存在?在我看来,除守护进程和nohup
程序之外的所有内容都将在注销期间被杀死。如果sleep
能这样生存下去,是不是就代表我可以用这个方法代替nohup
命令了?
除非bash
生成的实例设置了ssh
该huponexit
选项,否则在退出/注销时不会以任何方式终止任何进程,并且当huponexit
设置了该选项时,kill -9
在 shell 上使用不是nohup
在 shell 子进程上使用的好选择;nohup
在 shell 的子进程上仍然会保护它们免受不是来自 shell 的 SIGHUP 的影响,即使这并不重要nohup
仍然是首选,因为它允许 shell 优雅地终止。
在bash
有所谓的一个选项huponexit
,如果设置该将使bash
SIGHUP其子女在退出/注销;
在交互式非登录 bash
实例中,例如在由bash
产生的实例中gnome-terminal
,此选项将被忽略;无论huponexit
是设置还是未设置,退出时bash
都不会 SIGHUPped 的孩子bash
;
在交互式登录 bash
实例中,例如在由bash
产生的实例中ssh
,不会忽略此选项(但默认情况下未设置);如果huponexit
设置,退出/注销时,bash
的子项将被 SIGHUPped bash
;如果huponexit
未设置,bash
则bash
退出/注销时不会对 的孩子进行 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
),这允许它优雅地退出。
该&
进程在后台启动。如果输入ps -ef
,您将看到 sleep 的父进程 ID (PPID) 是您的 bash。然后注销并再次登录。注销后该进程将继续运行。第二次登录后ps -ef
再次运行。您将看到现在您的睡眠进程的父进程将是 ID 为“1”的进程。那就是init,所有进程的父进程。
归档时间: |
|
查看次数: |
6925 次 |
最近记录: |