退出Shell后,后台作业会怎样?


9

从我的理解,工作是管道从某一个shell启动的,你可以管理这些作业(fgbg,按Ctrl-Z)从该壳体内。一个作业可以包含多个进程/命令。

我的问题是,当包含外壳的原始外壳退出时,这些作业会发生什么?假设未设置huponexit,因此退出shell后后台进程继续运行。

假设我已经完成:

$ run.sh | grep 'abc' &
[1] job_id

然后我退出这个外壳。我将输入一个新的shell并运行jobs,显然看不到任何内容。但是我可以做ps aux | grep run.sh并看到此过程正在运行,并且我也将ps aux | grep grep看到并grep 'abc'正在运行该过程。

有没有一种方法可以获取完整管道的作业ID,以便我可以一口气杀死它,或者一旦退出原始Shell,是否必须与另一个Shell分别杀死所有进程?(我已经尝试了后者,但它确实有效,但是跟踪所有过程似乎很麻烦。)

Answers:


7

当外壳退出时,它可能将HUP信号发送到后台作业,这可能导致它们退出。仅当外壳本身收到SIGHUP时才发送SIGHUP信号,即仅在终端消失时(例如,由于终端仿真器进程终止),而在您正常退出外壳(使用exit内置方法或通过键入Ctrl+ D)时才发送。请参阅在什么情况下注销时SIGHUP不会发送到作业?有上一个子进程与其父去世任何UNIX变种?更多细节。在bash中,您可以设置该huponexit选项以在正常退出时也将SIGHUP发送到后台作业。在ksh,bash和zsh中,调用disown在作业上将其从要发送SIGHUP的作业列表中删除。接收到SIGHUP的进程可能会忽略或捕获信号,然后它不会消失。nohup在运行程序时使用它可以使其免受SIGHUP的影响。

如果由于可能出现的SIGHUP导致进程未终止,那么它将保留在后面。没有什么可以将其与外壳中的作业编号相关联了。

如果该过程尝试访问终端,但该终端不再存在,则该过程可能仍会终止。这取决于程序对不存在的终端的反应。

如果作业包含多个流程(例如管道),则所有这些流程都在一个流程组中。精确地发明了过程组以捕获由多个相关过程组成的shell作业的概念。您可以通过显示进程组ID(PGID,通常是组中第一个进程的进程ID)来查看按进程组分组的进程,例如ps l在Linux下或类似的ps -o pid,pgid,tty,etime,comm可移植进程。

您可以通过向传递否定参数来终止组中的所有进程kill。例如,如果您确定要终止的管道的PGID为1234,则可以使用以下命令终止它

kill -TERM -1234

2

通常,它们仍然运行,但是如果您忘记或改变了主意,则应该使用nohup,但请使用disown。

mike@mike-laptop4:~$ sleep 500
^Z
[1]+  Stopped                 sleep 500
mike@mike-laptop4:~$ bg
[1]+ sleep 500 &
mike@mike-laptop4:~$ jobs
[1]+  Running                 sleep 500 &
mike@mike-laptop4:~$ disown %1
mike@mike-laptop4:~$ jobs
mike@mike-laptop4:~$ 

并杀死您可以使用ps -ef --forest检查父项bash,如果bash具有后台功能,则可能还需要杀死它们
mikejonesey 16-10-23
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.