linux - 带有捕获信号的 shell 脚本不会忽略信号
问题描述
我正在开发一个测试自动化系统,我想出了一些行为不端的程序。对于第一个,我已经遇到了一些意想不到的行为。
trap "echo No thanks" INT
echo Let me just chill for $1 sec
sleep $1
echo All finished
观察到的行为:
- 发送 SIGINT 会导致打印“不,谢谢”,睡眠显然会立即中断,之后也会立即打印“全部完成”。
- 无论信号是单独发送还是使用键盘 ctrl+c 执行,行为都是相同的。
- 如果睡眠是背景的并且我们支持它,则会观察到相同的行为
wait
。
预期行为:
- 只要睡眠运行,向进程发送 SIGINT 应该会导致打印“不,谢谢”,然后在睡眠结束后退出之前打印“全部完成”。
如果睡眠是后台运行的,则发出键盘 ctrl+c 应该将 SIGINT 发送到进程组,这将包括睡眠,因此应该过早停止它。我不确定会发生什么
问题:
- 如何获得所需的行为?
- 为什么它的行为是这样的(与我的预期不同)?
这个问题本质上是一个骗局,但该答案没有令人满意的解释。
解决方案
目前:
bash
等待sleep
退出bash
并sleep
接收信号sleep
死bash
完成等待并运行陷阱
这会阻止您想要的行为,因为:
- 你
sleep
不想死 - 您不想
bash
在运行陷阱之前等待命令完成
要解决此问题,您可以sleep
忽略 sigint,并在循环中bash
运行wait
,以便主脚本在 ctrl-c 后重新获得控制权,但仍等待sleep
完成:
trap 'echo "No thanks"' INT
echo "Let me just chill for $1 sec"
# Run sleep in the background
sleep "$1" &
# Loop until we've successfully waited for all processes
until wait; do true; done
echo "All finished"
推荐阅读
- matlab - matlab中如何计算cieplot 1931色度图?
- excel - 如何使用 VBA-Excell 检查特定名称的工作表上每个组合框的名称?
- javascript - React:如何在表单提交时正确路由?
- javascript - 仅当不为空时才向对象添加值 - 不起作用
- unit-testing - 如何模拟根据接收到的参数返回不同值的方法?
- c++ - 多个锐利边缘/特征的不同 3D 网格密度?即分级 tet-mesh 密度
- python - addinfourl 实例没有属性“__getitem__”
- eclipse - Eclipse CDT 内容辅助方法参数提示弹窗位置
- python-3.x - 为什么我没有看到其他班级的标签?
- tsql - 如何对包含连字符的凭证编号进行排序,如 SI-18-08-1、CRV-18-09-1