为什么使用 "> /dev/null 2>&1 &" 执行时作业不会在注销时被终止?

为什么使用 "> /dev/null 2>&1 &" 执行时作业不会在注销时被终止?

当您运行如下例所示的作业时,它们会在您注销时被终止:

$ ./job.sh &

但是,当您按照下面的示例执行它们时,将 stdout 重定向到 stdout/dev/null并将 stderr 重定向到 stdout 并将作业置于后台,当您注销时它们不会被杀死。它有点像 nohup,只不过输出转到/dev/null文件而不是文件。

$ ./job.sh > /dev/null 2>&1 &

我注意到有些守护进程是这样​​工作的,然后我很好奇为什么它们在注销时没有被杀死。

有人可以解释一下为什么吗?

编辑1:

正如 @Patrick 在他的评论中所建议的,我尝试了同样的最简单的工作,结果是一样的:当我注销时,工作不会消失。

# while true; do sleep 1; done > /dev/null 2>&1 &
[1] 4320
# logout

luis-macbook:~ luis$
luis-macbook:Downloads luis$ ssh server
luis.alen@server's password: 
# jobs
#
# ps -ef | grep 4320
root      4320     1  0 01:17 ?        00:00:00 -bash

编辑2:

按照帕特里克的再次要求,我在没有重定向流的情况下进行了相同的测试,令我惊讶的是,该进程并没有终止。现在我完全困惑了......我发誓我记得当你注销时放入后台的进程就会消失。我完全错了吗?

# while true; do sleep 1; done &
[1] 20720
# logout
luis-macbook:~ luis$ ssh server
# jobs
#
# ps -ef | grep 20720
root     20720     1  0 23:31 ?        00:00:00 -bash

答案1

至于执行此操作的守护进程,这是因为它们希望丢弃它们可能产生的任何输出或错误消息,无论您如何重定向进程的输入和输出流,如果它附加到会话并且该会话是,它仍然会发出 SIGHUP 信号。关闭以保持进程运行。

要使进程保持运行,有几种方法:

  1. 将它们从会话中分离出来 — 守护进程通过分叉一个新进程然后退出原始进程来实现这一点;现在新进程没有父进程,并且被你采用,你init 也可以使用 bash 内部命令 disown 来实现这一点

  2. 用于nohup在会话终止时阻止进程接收 SIGHUP;该进程没有得到 SIGHUP,没有退出,它的父进程死亡并且 init 采用它

  3. 将其附加到不会消失的会话 - 使用 screen

请重新检查您对语句“执行时作业不会在注销时被终止> /dev/null 2>&1 &”的工作

答案2

据我所知,这是 bash 上作业的行为,我在这里做了一个测试,它也随着这些流的打开而继续运行:

sergiopa@sergiopa:~/Downloads$ find / -print >/dev/null 2>&1 &
[1] 14152
sergiopa@sergiopa:~/Downloads$ jobs
[1]+  Running                 find / -print > /dev/null 2>&1 &
sergiopa@sergiopa:~/Downloads$ ps -ef | grep find
sergiopa 14152 13913 10 15:47 pts/18   00:00:01 find / -print
sergiopa 14195 13913  0 15:48 pts/18   00:00:00 grep --color=auto find
sergiopa@sergiopa:~/Downloads$ 

sergiopa@sergiopa:~/Downloads$ lsof -c find
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
find    14152 sergiopa  cwd    DIR  252,1     4096     4808 /usr/src/linux-headers-2.6.35-22/drivers/rapidio
find    14152 sergiopa  rtd    DIR  252,1     4096        2 /
find    14152 sergiopa  txt    REG  252,1   141980   391686 /usr/bin/find
find    14152 sergiopa  mem    REG  252,1  1421892    26489 /lib/libc-2.12.1.so
find    14152 sergiopa  mem    REG  252,1   118084    26452 /lib/ld-2.12.1.so
find    14152 sergiopa  mem    REG  252,1   149392    26485 /lib/libm-2.12.1.so
find    14152 sergiopa  mem    REG  252,1    30684    26469 /lib/librt-2.12.1.so
find    14152 sergiopa  mem    REG  252,1   121578    26490 /lib/libpthread-2.12.1.so
find    14152 sergiopa  mem    REG  252,1  2768240   391861 /usr/lib/locale/locale-archive
find    14152 sergiopa    0u   CHR 136,18      0t0       21 /dev/pts/18 <<<<
find    14152 sergiopa    1w   CHR    1,3      0t0     4293 /dev/null   <<<<
find    14152 sergiopa    2w   CHR    1,3      0t0     4293 /dev/null   <<<<
find    14152 sergiopa    3r   DIR  252,3     4096 16777344 /home/sergiopa/Downloads
find    14152 sergiopa    4r   DIR  252,3     4096 16777344 /home/sergiopa/Downloads
find    14152 sergiopa    5r   DIR  252,1     4096     4808 /usr/src/linux-headers-2.6.35-22/drivers/rapidio
sergiopa@sergiopa:~/Downloads$ 

请参阅带有“<<<<”的行,这些行是 STDIN、STDOUT 和 STDERR。关闭 shell 但 find 仍在运行。

相关内容