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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27694818/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 12:05:12  来源:igfitidea点击:

Interrupt sleep in bash with a signal trap

bashshell

提问by John Morris

I'm trying to catch the SIGUSR1signal in a bash script that is sleeping via the sleepcommand:

我正在尝试SIGUSR1通过以下sleep命令在休眠的 bash 脚本中捕获信号:

#!/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 10has finished.
It appears the bash signal handling waits until the current command finished before processing the signal.

信号陷阱有效,但在sleep 10完成之前不会显示正在回显的消息。
bash 信号处理似乎在处理信号之前等待当前命令完成。

Is there a way to have it interrupt the running sleepcommand as soon as it gets the signal, the same way a C program would interrupt the libc sleep()function?

有没有办法sleep让它在收到信号后立即中断正在运行的命令,就像 C 程序中断 libcsleep()函数一样?

回答by Hans Klünder

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

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

回答by Echoes_86

Just a point about the waitafter the sleepbecause I've just made this error in my script:

只是关于wait之后的一点,sleep因为我刚刚在我的脚本中犯了这个错误:

You should use wait $!instead of waitif, inside your script, you already launched other processes in background

您应该在脚本中使用wait $!而不是waitif,您已经在后台启动了其他进程

For example, the waitinside the next snippet of code will waitfor the termination of both process_1and sleep 10:

例如,wait下一个代码片断里面会等待两个终止process_1sleep 10

process_1 &
  ...
sleep 10 &
wait  

If you use, instead of wait, wait $!your script will wait only for sleep 10, because $!means PID of last backgrounded process.

如果您使用,而不是waitwait $!您的脚本将只等待sleep 10,因为$!意味着最后一个后台进程的 PID

回答by dirk

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.

你会没事的。