简体   繁体   English

用信号陷阱中断bash中的睡眠

[英]Interrupt sleep in bash with a signal trap

I'm trying to catch the SIGUSR1 signal in a bash script that is sleeping via the sleep command: 我正试图在通过sleep命令睡眠的bash脚本中捕获SIGUSR1信号:

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

echo "Sleeping.  Pid=$$"
while :
do
    sleep 10
    echo "Sleep over"
done

The signal trap works, but the message being echoed is not displayed until the sleep 10 has finished. 信号陷阱起作用,但是在sleep 10结束之前不显示被回送的消息。
It appears the bash signal handling waits until the current command finished before processing the signal. 看起来bash信号处理在处理信号之前等待当前命令完成。

Is there a way to have it interrupt the running sleep command as soon as it gets the signal, the same way a C program would interrupt the libc sleep() function? 有没有办法让它在获取信号后立即中断正在运行的sleep命令,这与C程序中断libc sleep()函数的方式相同?

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

echo "Sleeping.  Pid=$$"
while :
do
   sleep 10 &
   wait $!
   echo "Sleep over"
done

Just a point about the wait after the sleep because I've just made this error in my script: 关于sleepwait的一点,因为我刚刚在我的脚本中犯了这个错误:

You should use wait $! 你应该使用wait $! instead of wait if, inside your script, you already launched other processes in background 如果在脚本中已经在后台启动了其他进程,则不要wait

For example, the wait inside the next snippet of code will wait for the termination of both process_1 and sleep 10 : 例如, wait下一个代码段内将等待双方的终止process_1sleep 10

process_1 &
  ...
sleep 10 &
wait  

If you use, instead of wait , wait $! 如果你使用,而不是waitwait $! your script will wait only for sleep 10 , because $! 你的脚本只会等待sleep 10 ,因为$! means PID of last backgrounded process . 表示最后一个后台进程的PID

Remark that 备注

sleep infinity &
wait

puts the sleep in background, and stops the wait with the signal. 将睡眠置于后台,并使用信号停止等待。 This leaves an infinite sleep behind on every signal ! 这会在每个信号上留下无限的睡眠!

Replace the sleep and wait with 更换睡眠并等待

read

and you will be fine. 你会没事的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM