空闲 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 有必要吗? 我刚刚尝试了这个解决方案,不管有没有&lt; /dev/tty,结果似乎是一样的。 @123,这可能是必要的,具体取决于脚本正在执行的其他操作。例如,从 stidn 中读取规则,并以 yourscript &lt;firewall-rules 运行它,然后 read 需要 &lt;/dev/tty。如果没有指定环境(因为它没有),我将假设最坏的情况(或者让我必须假设某些事情,比如 TTY 的可用性,明确的) . @boolean.is.null, ...见上文; &lt;/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 '' _ &lt;/dev/tty 有问题,我将它放在脚本中以防止它退出并终止作业。我有另一个使用dialog 并调用第一个脚本作为工作的脚本,当脚本到达read -r -d '' _ &lt;/dev/tty 时,父脚本对话框有一个非常奇怪的行为,就像有人不断按下Esc 键,这使得对话框尝试退出。

我建议使用sleep,你可以睡很长时间,比如999天sleep 999d,如果你需要确保它永远不会停止,你可以把它放在一个while循环中。

【讨论】:

一些系统还支持sleep infinity 休眠非常长时间

以上是关于空闲 bash 脚本,直到记录 CTRL+c 事件的主要内容,如果未能解决你的问题,请参考以下文章

2018-9-17-bash之信号捕捉

python 获取控制台被关闭事件和ctrl+c事件 脚本

sh 用于监视日志并在空闲时重新启动服务的BASH脚本。

如何编写一个运行程序的 bash 脚本,直到它检测到信号 SIGSEGV、分段错误?

Bash 脚本和 C++ 之间的持久 IPC

linux shell ctrl+c 为啥可以退出进程