空闲 bash 脚本,直到记录 CTRL+c 事件
Posted
技术标签:
【中文标题】空闲 bash 脚本,直到记录 CTRL+c 事件【英文标题】:Idle bash script until CTRL+c event is logged 【发布时间】:2016-08-27 18:38:33 【问题描述】:我有一个 bash 脚本可以完成一些工作,而且完成得相当快。 然后它应该空闲,直到用户决定终止它,然后是一些清理代码。
这就是我使用以下代码捕获 CTRL+c 事件的原因:
control_c()
cleanup
exit 0
trap control_c SIGINT
但由于我的脚本完成得很快,我永远不会故意终止它,所以它永远不会捕获 CTRL+c 并运行清理代码。
我想我可以实现一个无限的do while
循环,在脚本末尾加上sleep
,但我认为有更好的解决方案。
如何在 bash 中闲置脚本,期待 CTRL+c 事件?
【问题讨论】:
顺便说一句,为什么不把它放在一个通用的 EXIT 陷阱中呢?trap cleanup 0
并且您不再依赖于如何退出的细节,只要它不是像 SIGKILL 这样根本无法被困住的东西。
我认为这在我的情况下是不可能的。该脚本启用了一堆 iptables
规则,这些规则只有在用户决定不再需要之前才有效。
我并不是说你不等待 ctrl+c 或 enter 或其他什么,我只是说你使用 EXIT 陷阱而不是 SIGINT 陷阱——这样它仍然会触发不基于 SIGINT 的退出。
【参考方案1】:
假设您已连接到 TTY:
# idle waiting for abort from user
read -r -d '' _ </dev/tty
【讨论】:
引导 /dev/tty 有必要吗? 我刚刚尝试了这个解决方案,不管有没有< /dev/tty
,结果似乎是一样的。
@123,这可能是必要的,具体取决于脚本正在执行的其他操作。例如,从 stidn 中读取规则,并以 yourscript <firewall-rules
运行它,然后 read
需要 </dev/tty
。如果没有指定环境(因为它没有),我将假设最坏的情况(或者让我必须假设某些事情,比如 TTY 的可用性,明确的) .
@boolean.is.null, ...见上文; </dev/tty
是一种健壮性改进,即使脚本从其他地方获取输入,也可以使用它。
如果您没有连接到任何 TTY 而只是在本地连接怎么办,那么解决方案是什么?我的脚本等待这段代码,但之后它不会执行脚本的其余部分【参考方案2】:
下面会等待Ctrl-C,然后继续运行:
( trap exit SIGINT ; read -r -d '' _ </dev/tty ) ## wait for Ctrl-C
echo script still running...
【讨论】:
我没有测试所有场景,但这可能是bash
特定的。在 GNU makefile 中,它可能需要 SHELL = bash
。【参考方案3】:
read -r -d '' _ </dev/tty
有问题,我将它放在脚本中以防止它退出并终止作业。我有另一个使用dialog
并调用第一个脚本作为工作的脚本,当脚本到达read -r -d '' _ </dev/tty
时,父脚本对话框有一个非常奇怪的行为,就像有人不断按下Esc
键,这使得对话框尝试退出。
我建议使用sleep
,你可以睡很长时间,比如999天sleep 999d
,如果你需要确保它永远不会停止,你可以把它放在一个while循环中。
【讨论】:
一些系统还支持sleep infinity
休眠非常长时间以上是关于空闲 bash 脚本,直到记录 CTRL+c 事件的主要内容,如果未能解决你的问题,请参考以下文章