从https://unix.stackexchange.com/a/43709/674
对于
kill
由管理的所有后台作业bash
,请执行kill $(jobs -p)
是否kill $(jobs -p)
仅杀死当前 shell 中那些“正在运行”的后台作业,而不杀死 shell 中处于“停止”或其他状态的后台作业?
我们如何杀死当前 shell 中的所有后台作业,无论它们是处于运行、停止还是其他状态?
例如,我通过运行less
然后创建了两个停止的作业ctrl+z
:
$ ps | less
[1]+ Stopped ps | less
$ less recover_jobs.sh
[2]+ Stopped less recover_jobs.sh
$ jobs -l
[1]- 2753 Done ps
2754 Stopped | less
[2]+ 2842 Stopped less recover_jobs.sh
$ jobs -p
2753
2842
$ kill $(jobs -p)
bash: kill: (2753) - No such process
$ kill 2754
$ kill 2842
$ jobs -l
[1]- 2753 Done ps
2754 Stopped | less
[2]+ 2842 Stopped less recover_jobs.sh
$ fg 1
ps | less
Terminated
$ fg 2
less recover_jobs.sh
Terminated
我想知道为什么:
kill $(jobs -p)
不会扼杀任何stopped
工作,jobs -p
不显示已停止作业的 pid 2754| less
,而是显示已完成作业的 pid 2753ps
,kill 2754
并且kill 2842
不要终止| less
和 的已停止工作less recover_jobs.sh
,并且- 当我
fg
停止工作时,它们会立即显示Terminated
,但不是在我之前fg
显示?
谢谢。
答案1
kill $( jobs -p )
会发送TERM
向所有人发送信号工作,无论它们是否正在运行。一个作业可能包括多个进程,但只有每个作业中的第一个进程会收到信号(请参阅下文)。
您的第一个问题、第三个问题和最后一个问题的答案相同。停止的作业不会收到任何信号。信号处理程序(即使是默认的)在进程中运行,并且该进程是停止了。信号是发表当工作恢复时。
至于第二个问题,我认为jobs -p
只会给你该进程的进程ID第一的管道中的进程,而jobs -l
列出属于所有作业的所有进程。终止管道的第一个进程将关闭下一个进程正在读取的文件描述符,从而在下次尝试读取时提示文件结束。