这个命令有什么问题吗?
$ trap 'killall $$ ; rm -f $folder2;exit ' 18 20 24
该命令处于for
循环中,在for
执行时,如果我按CTRL-Z我希望它停止该进程并删除创建的所有文件(在 内部folder2
)及其folder2
本身。
但是当我在终端中按CTRL-时,它会停止,但之后我无法做任何其他事情,甚至-也不起作用。ZCTRLC
答案1
问题是,在提供当前进程 PID 的killall
同时,需要一个与进程名称而不是其 PID 匹配的模式。$$
你想用它kill
来代替。
另外,如果您想删除目录及其所有内容,则需要切换-r
到rm
:
最后,终止进程后所做的任何操作都不会生效:将 移至kill
的末尾trap
并完全删除exit
:
trap 'rm -rf "$folder2";kill $$' 18 20 24
如果您想for
在删除之前停止循环$folder2
,您可以使用break
:
trap 'break;rm -rf "$folder2";kill $$' 18 20 24
答案2
以下面的脚本为例:
#!/bin/bash
trap 'echo bye; kill $$' SIGTSTP
sleep 30
假设您在睡眠期间按下了 Control-Z。这会将 SIGTSTP 发送到进程组,其中包括 sleep 和 bash。正如中所解释的William Pursell 在 Stack Overflow 上对类似问题的回答trap
bash在运行命令 ( ) 终止之前不会运行处理程序sleep
。但是,sleep 不会终止:它已暂停,因为它还收到了 SIGTSTP。此时,因为它已停止,所以它将忽略 control-C (SIGTERM)、control-\ (SIGQUIT) 等。除了 SIGKILL 之外,任何其他操作都不会使其停止运行。
所以你trap
不会运行(除非你继续杀死-9睡眠,然后它会立即运行)。
为了解决这个问题,您需要让你的子进程被忽略或者没有收到 SIGTSTP,然后自己处理杀死它们。或者在后台运行它们,并wait
为它们:
#!/bin/bash
trap 'echo bye; kill $$' SIGTSTP
sleep 30 &
wait
Control-Z 实际上可以按预期工作。