![如何使用 Ctrl+C 终止 Bash 脚本中启动的所有后台进程?](https://linux22.com/image/1504986/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20Ctrl%2BC%20%E7%BB%88%E6%AD%A2%20Bash%20%E8%84%9A%E6%9C%AC%E4%B8%AD%E5%90%AF%E5%8A%A8%E7%9A%84%E6%89%80%E6%9C%89%E5%90%8E%E5%8F%B0%E8%BF%9B%E7%A8%8B%EF%BC%9F.png)
ArchLinux(Manjaro)。
我正在运行一个 bash 文件。它使用 运行 2 个进程(命令)&
。但是当我按Ctrl+C停止程序时 - 一个进程终止,而另一个进程继续运行。
我该如何停止这两个进程?或者我该如何编写一个新脚本来终止这两个进程?
答案1
更新:trap
需要SIG
根据条件删除前缀,尽管有些 shell 支持包括它。请参阅下面的注释。
和号“&”在后台的新进程中运行命令。当其父进程(在您的情况下运行 bash 脚本的命令)结束时,此后台进程会将其父进程重置为 init(进程号为PID
1),但不会终止。当您按下 时ctrl+c
,您正在向前台进程发送中断信号,并且它不会影响后台进程。
为了终止后台进程,您应该使用kill
带有PID
最新后台进程的命令,该命令可以通过获取$!
。
如果您希望使用它ctrl+c
来终止脚本和后台进程,您可以执行以下操作:
trap 'kill $BGPID; exit' INT
sleep 1024 & # background command
BGPID=$!
sleep 1024 # foreground command of the script
trap
修改的陷阱处理程序 SIGINT
(trap
需要删除SIG
前缀,但某些 shell 可能支持包含它),因此脚本将$BGPID
在退出之前终止该进程。
答案2
程序可以忽略Ctrl+c
信号,就像它们也可以忽略 SIGTSTP 一样
你可以在大多数 shell 中尝试Ctrl+z
(并非总是,但大多数时候)
有些信号进程不能忽略:SIGKILL、SIGSTOP。您可以发送 kill 命令。要杀死冻结的进程,您必须找到进程 ID (PID)。
使用 pgrep 或 ps 然后杀死它
% kill -9 PID