在 shell 脚本中实现无限等待 [英] Implementing infinite wait in shell scripting

查看:127
本文介绍了在 shell 脚本中实现无限等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能听起来微不足道,但我很确定没有人问过这个问题,或者至少我找不到.

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. 虽然为真;做睡眠1;done 这几乎搞定了,但是由于 sleep 是一个外部命令,当我向正在运行的脚本发送一个 SIGTERM 时,它必须等待 sleep 先完成再处理信号.将 sleep 1 更改为类似 sleep 10 的内容,延迟会很明显.此外,该解决方案每 1 秒唤醒一次 CPU,这并不理想.
  2. 虽然为真;阅读;donestdin 为 tty 时,这是完美的.read 是内置的 shell,SIGTERM 立即到达脚本.但是,当 stdin/dev/null 时,脚本会无助地在 /dev/上永远运行 read,从而耗尽所有 CPUnull.
  1. while true; do sleep 1; done This almost gets it, but since sleep is an external command, when I send a SIGTERM to the running script, it has to wait for the sleep to finish first and then process the signal. Change sleep 1 to something like sleep 10 and the lag will be obvious. Also the solution wakes up the CPU every 1 second, which is not ideal.
  2. while true; do read; done This is perfect when stdin is tty. read is a shell builtin and SIGTERM arrives at the script instantly. But, when stdin is /dev/null, the script eats up all the CPU by helplessly running read forever on /dev/null.

因此需要一个永远等待的shell 内置结构.浏览 man dash 我没有找到这样的 - 唯一的阻塞内置函数是 readwait,我不知道如何我可以使用 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 脚本中实现无限等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆