为什么由bash脚本启动的进程在terminalclosures后不会退出?

情况1:

我在gnome-terminal中执行sleep 1000 & ,然后closuresterminal。 sleep过程不存在。

案例2:

这是一个脚本t.sh

 #!/usr/bin/env bash sleep 1000 & 

我在gnome-terminal中执行./t.sh然后closuresterminal。 存在sleep过程(由ps aux知道)。 这个过程不应该结束吗?

JürgenHötzel在答案中说的是真实的,但这不完全是这样。

情况1:

gnome-terminal关闭时,tty(包括pty)驱动程序会得到tty的断开连接事件,并将sIGHUP发送到与tty关联的控制进程 。 这里的控制过程是bash,bash将收到SIGHUP 。 然后,根据bash手册 :

  • 收到SIGHUP后,shell会默认退出。 在退出之前, 交互式shellSIGHUP重新发送到所有正在运行或停止的作业。 停止的工作发送SIGCONT以确保他们收到SIGHUP

  • 如果已经使用shopt设置了huponexit shell选项,则当交互式登录shell退出时,bash将向所有作业发送SIGHUP

因此,对于情况1,bash将重新发送SIGHUP到将被信号杀死的后台作业sleep (这是SIGHUP的默认行为)。

huponexit提到的huponexit选项只会影响自动退出的交互式登录shell ,但是对于情况1,bash被SIGHUP所杀死,并且在gnome-terminal中运行bash不一定是登录shell,尽管它实际上是一个交互式shell 。)

案例2:

这里有2个bash进程:

  • bash#1:在gnome-terminal中运行的bash进程。
  • bash#2:运行t.sh脚本的bash进程。

t.sh (bash#2)正在运行时, sleep 1000 &开始作为bash#2的后台作业。 在t.sh (bash#2)退出之后, sleep将继续运行,但是它将成为孤立进程, init进程会照顾它, sleep的PPID将变成1( init进程的PID)。

当gnome终端关闭时,bash#1将收到SIGHUP,bash#1将重新发送SIGHUP给所有的作业。 但sleep不是bash#1的工作,所以sleep不会收到SIGHUP,所以在bash#1完成之后它将继续运行。

当使用交互式登录shell时,如果设置了这个选项,bash会在退出时发送一个HUP信号给你的作业:

 juergen@samson:~ → shopt huponexit huponexit on 

默认处理程序将终止您的过程。 启动非交互式 bash(如脚本)时, huponexit选项无效。 请参阅: https : //www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html

简而言之,不。 使用“&”,您正在使当前进程作为后台进程运行。 据我所知,你必须明确地杀死它。