【发布时间】:2012-01-29 11:33:08
【问题描述】:
这听起来可能微不足道,但我很确定这个问题没有被问到,或者至少我找不到。
我正在寻找一种使用 shell 脚本构造 无限等待(不一定是循环)的方法,以便它永远等待并且可以被杀死(或者在技术上, 接收SIGTERM)。以下是已知的可能构造和反对它们的论据:
-
while true; do sleep 1; done这差不多就明白了,但是由于sleep是外部命令,所以当我向运行脚本发送SIGTERM时,它必须先等待sleep完成,然后再处理信号。将sleep 1更改为sleep 10之类的东西,滞后会很明显。此外,该解决方案每 1 秒唤醒一次 CPU,这并不理想。 -
while true; do read; done当stdin是 tty 时,这是完美的。read是一个内置的 shell,SIGTERM立即到达脚本。但是,当stdin是/dev/null时,脚本会无助地在/dev/null上永远运行read,从而耗尽所有CPU。
因此,需要一个永久等待的 shell 内置构造。浏览man dash 我没有找到这样的——唯一的阻塞内置函数是read 和wait,我不知道如何使用wait 构建一个理想的。
答案应该适用于 POSIX shell(实际上是 dash),或者不太适用于 Bash。
补充说明。
第一个示例不能完美运行的情况比我想象的要复杂。使用以下 shell 脚本:
#!/bin/sh
echo $$
while true; do
sleep 100
done
如果你在另一个 tty 上杀死它,它会立即终止。当您尝试进行诱捕时,有趣的事情就开始了。使用此脚本:
#!/bin/sh
at_term() {
echo 'Terminated.'
exit 0
}
trap at_term TERM
echo $$
while true; do
sleep 20
done
示例 1 中准确描述了发生的情况。这发生在 bash、dash 和 zsh 中。正是在这种情况下,我正在寻求一个“完美”的无限外观构造。
【问题讨论】:
-
当我将
SIGTERM发送给dash在循环中执行sleep 100时,它会立即退出。 -
你需要这个做什么?如果进程应该持续但什么都不做,它可以给自己发送一个
SIGSTOP。