问题描述
这可能听起来微不足道,但我很确定没有人问过这个问题,或者至少我找不到.
This may sound trivial, but I'm pretty sure this question hasn't been asked, or at least I can't find it.
我正在寻找一种使用 shell 脚本构建无限等待(不一定是循环)的方法,以便它永远等待并且可以被杀死(或技术上, 以接收 SIGTERM
).以下是已知的可能构造和反对它们的论据:
I'm looking for a way to construct an infinite wait (not necessarily a loop) with shell scripting so that it waits forever and can be killed (or technically, to receive a SIGTERM
). The following are known possible constructs and arguments against them:
虽然为真;做睡眠1;done
这几乎搞定了,但是由于sleep
是一个外部命令,当我向正在运行的脚本发送一个SIGTERM
时,它必须等待sleep
先完成再处理信号.将sleep 1
更改为类似sleep 10
的内容,延迟会很明显.此外,该解决方案每 1 秒唤醒一次 CPU,这并不理想.虽然为真;阅读;done
当stdin
为 tty 时,这是完美的.read
是内置的 shell,SIGTERM
立即到达脚本.但是,当stdin
为/dev/null
时,脚本会无助地在/dev/上永远运行
.read
,从而耗尽所有 CPUnull
while true; do sleep 1; done
This almost gets it, but sincesleep
is an external command, when I send aSIGTERM
to the running script, it has to wait for thesleep
to finish first and then process the signal. Changesleep 1
to something likesleep 10
and the lag will be obvious. Also the solution wakes up the CPU every 1 second, which is not ideal.while true; do read; done
This is perfect whenstdin
is tty.read
is a shell builtin andSIGTERM
arrives at the script instantly. But, whenstdin
is/dev/null
, the script eats up all the CPU by helplessly runningread
forever on/dev/null
.
因此需要一个永远等待的shell 内置结构.浏览 man dash
我没有找到这样的 - 唯一的阻塞内置函数是 read
和 wait
,我不知道如何我可以使用 wait
构建一个理想的.
Thus a shell builtin construct that waits forever is required. Skimming through man dash
I didn't find such one - the only blocking builtins are read
and wait
, and I don't have idea how I can construct an ideal one using wait
.
答案应该适用于 POSIX shell(实际上是 dash
),或者不太好,Bash.
The answer should be applicable to POSIX shell (effectively dash
), or less preferably, Bash.
附加说明.
第一个示例无法完美运行的情况比我想象的要复杂.使用以下 shell 脚本:
The situation where the first example doesn't work perfectly is more complex than I thought. With the following shell script:
#!/bin/sh
echo $$
while true; do
sleep 100
done
如果你在另一个 tty 杀死它,它会立即终止.当您尝试诱捕时,有趣的事情就开始了.使用此脚本:
if you kill it at another tty, it terminates immediately. The funny thing begins when you attempt to do trapping. With this script:
#!/bin/sh
at_term() {
echo 'Terminated.'
exit 0
}
trap at_term TERM
echo $$
while true; do
sleep 20
done
发生的情况在示例 1 中得到了准确描述.这发生在 bash、dash 和 zsh 中.正是在这种情况下,我正在寻求一种完美"的无限外观结构.
What happens is exactly described in example 1. This happens with bash, dash and zsh. And it's under this condition that I'm seeking a "perfect" infinite look construct.
推荐答案
您可以使用命名管道进行阅读:
you can use a named pipe for your read:
mkfifo /tmp/mypipe
#or mknode /tmp/mypipe p
如果您以后想向管道发送不同的任意信号",可以将读取与 case 语句结合使用以采取适当的操作(甚至是有用的操作)
if you later want to send different arbitrary "signals" to the pipe, the read can be use in combination with a case statement to take appropriate actions (even useful ones)
while read SIGNAL; do
case "$SIGNAL" in
*EXIT*)break;;
*)echo "signal $SIGNAL is unsupported" >/dev/stderr;;
esac
done < /tmp/mypipe
这篇关于在 shell 脚本中实现无限等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!