FreeBSDで無限の「while」ループを破る

FreeBSDで無限の「while」ループを破る

FreeBSDベアボーン端末専用システムがあります。私はzpool statusこれを15秒ごとに監視したいと思います。通常、「一般」システムでは使用されますwatch -n15が、ここでは使用できません。

重要で潜在的に脆弱なホストに新しいプログラムをインストールしたいかどうかわかりません。しかし、それが本当に簡単で喜んでいることを望むなら、という代替案を聞いたことがありますcmdwatch

私の監視プログラムの簡単な解決策は、whileループを使用することです。つまり:

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

これは表面的に作用します。しかし、今はCtrl + Cを使用してループを中断することができないので、これは大きな面倒です。 Ctrl + Zを使用してバックグラウンドにループを配置して呼び出してpsPIDを取得し、プログラムを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/パッケージ

バックグラウンドにループがある場合は、をfg押しますCtrl+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$

watch5秒の静的スリープ時間を持つシェル関数でこのユーティリティを非常に簡単に実装します。

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

答え3

トラップの使用を考えたことがありますか?

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

関連情報