linux - Bash 脚本捕获信号,但之后等待进程终止
问题描述
目前我正在编写这样的 bash 脚本:
foo(){
while true
do
sleep 10
done
}
bar(){
while true
do
sleep 20
done
}
foo &
bar &
wait
(我知道这样的脚本没有意义,它只是关于结构)
现在我想用trap -- <doSomething> RTMIN+1
. 这首先有效。当脚本接收到 rtmin+1 信号时,它会做 doSomething 但之后它存在(带有 163 退出代码,这是正在发送的信号的编号)。
这不是我想要的行为。我希望在收到信号后,脚本继续等待进程(在这种情况下是两个函数)终止(在这种情况下当然不会发生,但脚本应该等待)。
我尝试将 a 添加; wait
到接收信号时应该做的事情中,但这没有帮助(或者我做错了什么)。
有谁知道如何实现所需的行为?
提前致谢并致以最良好的祝愿。
编辑:也许一个更精确的例子有帮助:
clock(){
local prefix=C
local interval=1
while true
do
printf "${prefix} $(date '+%d.%m %H:%M:%S')\n"
sleep $interval
done
}
volume(){
prefix=V
volstat="$(amixer get Master 2>/dev/null)"
echo "$volstat" | grep "\[off\]" >/dev/null && icon="" #alternative: deaf: mute:
vol=$(echo "$volstat" | grep -o "\[[0-9]\+%\]" | sed "s/[^0-9]*//g;1q")
if [ -z "$icon" ] ; then
if [ "$vol" -gt "50" ]; then
icon=""
#elif [ "$vol" -gt "30" ]; then
# icon=""
else
icon=""
fi
fi
printf "${prefix}%s %3s%%\n" "$icon" "$vol"
}
clock &
volume &
trap -- "volume" RTMIN+2
wait
现在RTMIN+2
信号应该重新运行volume
函数,但clock
过程不应该被中断。(到目前为止,整个脚本(包括所有子进程)在收到信号后终止)
解决方案
当没有操作数调用时,以0wait
退出;这意味着调用 shell 已知的所有进程 ID 都已终止,或者值大于 128;这意味着接收到已设置陷阱的信号。因此,循环直到退出就足以让脚本在收到信号后保持活动状态。您也可以在循环中检查其退出状态是否小于 128,但我认为没有必要。wait
0
但是,如果您使用 发送这些信号pkill
,则在后台启动的作业也将接收它们,因为子进程从其父进程继承进程名称,而不是自定义信号处理程序,并向pkill
名称匹配的所有进程发出信号。你也需要处理这种情况。
一个最小的工作示例是:
#! /bin/bash -
# ignore RTMIN+1 and RTMIN+2 temporarily
# to prevent pkill from killing jobs
trap '' RTMIN+1 RTMIN+2
# start jobs
sleep 20 && echo slept for 20 seconds &
sleep 30 && echo slept for 30 seconds &
# set traps
trap 'echo received rtmin+1' RTMIN+1
trap 'echo received rtmin+2' RTMIN+2
# wait for jobs to terminate
until wait; do
echo still waiting
done
还值得注意的是RTMIN+1
,RTMIN+2
在开始作业之前忽略它们可以防止从它们下降的 shell 捕获/重置这些信号。如果这是一个问题,您可以按照 F. Hauri 的建议在工作中设置一个空陷阱;或者您可以完全放弃忽略并使用pkill
选项-o
将信号发送到最旧的匹配进程。
参考:
有关的:
推荐阅读
- linux - 需要重置 Solr 主目录
- typescript - 是否可以生成 TypeScript 类型定义/声明文件?
- c# - 两个应用程序是否可以创建同名的内存映射文件?
- performance - movq 在 x64-64 架构上比 mov 快吗?
- angular - 在角度响应上返回 json
- node.js - 如何使用 nodeJS 从 axios 库中获取有效的 JSON 响应
- wpf - 调整窗口大小时控件的滚动条被边框元素隐藏
- spring - 当我在春天创建我的休息服务时,mysql 会生成一个表而不是使用我拥有的表
- python-3.x - 如何悬停然后单击硒中的按钮?
- laravel - 根据我的搜索计算带有 laravel 的行数