目前我正在编写这样的 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 退出代码,这是发送的信号的编号)。

这不是我想要的行为。我希望在收到信号后,脚本继续等待进程(在这种情况下是两个函数)终止(在这种情况下当然不会发生,但脚本应该等待)。

我尝试添加 ; 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过程不应中断。 (到目前为止,整个脚本(包括所有子进程)在接收到信号时终止)

请您参考如下方法:

当没有操作数调用时,wait退出 0 ;这意味着调用 shell 已知的所有进程 ID 都已终止,或者 大于 128 的值;这意味着接收到已设置陷阱的信号。所以,循环直到 wait退出 0足以让脚本在收到信号后保持事件状态。您还可以在循环内检查其退出状态是否小于 128,但我认为没有必要。

但是,如果您使用 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+1RTMIN+2在开始作业之前可以防止从它们下降的 shell 捕获/重置这些信号。如果这是一个问题,您可以按照 F. Hauri 的建议在工作中设置一个空陷阱;或者你可以完全放弃忽略和使用 pkill-o选项将信号发送到最旧的匹配进程。

引用:
  • Shell Command Language § Signals and Error Handling
  • wait spec. § EXIT STATUS

  • 有关的:
  • Reliably kill sleep process after USR1 signal

  • 评论关闭
    IT序号网

    微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!