如何使ctrl + c / not /中断while循环?


11

鉴于此循环:

while sleep 10s ; do
  something-that-runs-forever
done

当我按Ctrl + C时,整个while循环都会中断。我想做的是中断“某事”过程,让10秒钟过去,然后重新启动“某事”。

如何使ctrl + c仅影响“某物”,而不影响while循环?

编辑:“中断”如SIGINT。杀。中止 终止。不像“暂停”中那样“中断”。


如果只想暂停它,为什么不使用Ctrl + Z,等待10秒钟并运行fg?为什么要完全使用Ctrl + C?
terdon

@terdon:感谢您的评论,也许我会急忙回答。需要阅读更多关于OP的要求
Inian

@terdon:我不想暂停它。就像我写的那样,我想过10秒。
老板

您说:What I want to do is to interrupt the "something"-process, let 10 seconds pass, and then restart "something"。如果您按Ctrl + Z,请等待10秒钟然后运行fg,这就是将要发生的情况。也许您可以编辑问题并举一个具体的例子,以便我们更好地理解?
terdon

3
我认为在Ctrl + C中断的上下文中是明确的,但显然我错了。我现在已经编辑。
老板

Answers:


18

如果您只是trap SIGINT想做某事,它应该可以工作。像:true)。

#!/bin/sh
trap ":" INT    
while sleep 10s ; do
    something-that-runs-forever
done

中断它们something...不会使shell现在退出,因为它会忽略该信号。但是,如果对sleep进程进行^ C ,它将退出并失败,并因此终止循环。将sleep移到循环的内部或添加类似的方法|| true来防止这种情况。

请注意,如果您用来trap "" INT完全忽略信号(而不是为其分配命令),则在子进程中也将忽略它,因此您也不能中断something...。至少Bash的手册中明确提到了这一点:

如果arg是空字符串,则每个sigspec指定的信号将被shell和它调用的命令忽略。[...] 进入外壳时忽略的信号无法捕获或重置。


在当前的shell中也可以实现吗?(不在脚本中。)

1
您可能要do (trap - INT; something-that-runs-forever)允许中断命令。另外,您无需运行:-您可以使用空字符串忽略信号:trap '' INT。所有这些都是POSIX,并且可以在任何兼容的Shell(不仅仅是Bash)上运行。
Toby Speight

还请注意SIGINT,完整编写并不是严格可移植的:“ 实现可能允许名称带有SIG前缀或忽略信号名称中的大小写作为扩展 ”(我强调)
Toby Speight,

您可以传递空字符串作为忽略信号的动作,例如trap "" INT(也可以是posix)
daf 18'Jan

@TobySpeight,我用的原因trap :,而不是trap ""正是,为了忽略的信号(但要无操作代替),这样我们就不需要做任何事情要能中断主something程序。
ilkkachu

0

另一种选择是something-that-runs-forever处理信号(在收到信号后优雅退出)。当然,只有在许多脚本中使用了该程序,并且CTRL+ 上的期望行为在C系统上都是相同的-继续执行脚本,才有意义。


ITYM是“睡眠并重新执行自身”,而不是“优雅退出”?
Toby Speight '18
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.