“陷阱 'killall $$ ; rm -f $folder2;exit ' 18 20 24

“陷阱 'killall $$ ; rm -f $folder2;exit ' 18 20 24

这个命令有什么问题吗?

$ trap 'killall $$ ; rm -f $folder2;exit ' 18 20 24

该命令处于for循环中,在for执行时,如果我按CTRL-Z我希望它停止该进程并删除创建的所有文件(在 内部folder2)及其folder2本身。

但是当我在终端中按CTRL-时,它会停止,但之后我无法做任何其他事情,甚至-也不起作用。ZCTRLC

答案1

问题是,在提供当前进程 PID 的killall同时,需要一个与进程名称而不是其 PID 匹配的模式。$$你想用它kill来代替。

另外,如果您想删除目录及其所有内容,则需要切换-rrm

最后,终止进程后所做的任何操作都不会生效:将 移至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 上对类似问题的回答trapbash在运行命令 ( ) 终止之前不会运行处理程序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 实际上可以按预期工作。

相关内容