打破 FreeBSD 上的无限“while”循环

打破 FreeBSD 上的无限“while”循环

我有一个FreeBSD只有终端的准系统。我想zpool status每 15 秒左右监控一次。通常在“常规”系统上我会使用,watch -n15但这在这里不可用。

我不知道是否要在重要且可能脆弱的主机上安装新程序。但如果它真的很简单,我愿意这样做,我听说过一个名为 的替代品cmdwatch

我监控程序的简单解决方案是使用 while 循环,即:

while :; do zpool status && sleep 15; done

这表面上是有效的。但是,现在我无法使用 Ctrl + C 来打破循环,这是一个很大的麻烦。我可以使用 Ctrl + Z 将循环放在后台,调用ps以获取 PID,然后kill -9调用程序。普通杀戮是没有作用的。

所以这还不够好。对于除我之外的任何用户来说,系统看起来都已损坏。另一篇文章指出我要检查返回码是否大于 128,SIGINT应该给出 130,就像这样

while [ 1 ]; do zpool status; test $? -gt 128 && break; done

如果我跑的话这有效仅有的命令sleep 15。将更多命令与;或链接在一起&&会产生我无法中断循环的旧情况。

我该怎么办?

答案1

添加终止条件:

canary=$(mktemp)
echo "Canary is $canary"
while [[ -f "$canary" ]]; do
    COMMAND
    sleep 15
done &

要逃脱,请杀死 ( rm) 金丝雀。

答案2

GNUwatch实用程序对于 FreeBSD 可用为端口gnu-watch/包

将循环置于后台后,只需fgCtrl+C

bash-4.4$  while true; do echo hello && sleep 2; done &
[1] 26130
bash-4.4$ hello
hello
hello
hello
hello
hello

bash-4.4$ fg
while true; do
    echo hello && sleep 2;
done
hello
^C
bash-4.4$

该实用程序的一个非常简单的实现,watch作为 shell 函数具有 5 秒的静态睡眠时间:

function watch
{
    while true; do 
        clear
        command "$@"
        sleep 5
    done
}

答案3

你有没有考虑过使用陷阱?

#! /bin/sh
trap "break" INT
while :
do
    COMMAND && sleep 15
done

相关内容