GNU/Linux >> Linux の 問題 >  >> Linux

シェル スクリプト while ループ:[ パイプラインの周りに `]' がありません

エラーは、最初の [ を削除する必要があることです 終了ステータスを確認したいので、コマンドを直接使用してください。

Shellcheck ツールの Wiki ページには、これに関する説明があります (issue SC1014):

<ブロック引用>

[ .. ] if のようなシェル構文の一部ではありません ステートメント。 C に似た言語 if (foo) { bar; } の括弧と同等ではありません 、テストするコマンドをラップしないでください。

[ whoami のような普通のコマンドです または grep 、しかし面白い名前が付いています (ls -l /bin/[ を参照) )。 test の省略形です .

特定のコマンドの終了ステータスを確認したい場合は、そのコマンドを直接使用してください。

コマンドの出力を確認したい場合は、 "$(..)" を使用してください その出力を取得してから test を使用します または [ /[[ 文字列比較を行うには:

ps aux | grep -q "[r]elayevent.sh" も使用 stdout に何かを出力する代わりに、サイレントに終了ステータスを取得するようにします .

または pgrep を使用できます 出力を /dev/null に送信します .

最後のケースではより効率的であるため、最初に 2 番目の条件を使用してください。

最終的なスクリプトは次のようになります:

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && ps aux | grep -q "[r]elayevent.sh"   ; do

    sleep 3

    let COUNTER+=1

done

または

#!/bin/bash
COUNTER=0

while [ "$COUNTER" -lt 10 ] && pgrep  "[r]elayevent.sh" >/dev/null  ; do

    sleep 3

    let COUNTER+=1

done

[ ... ] 内にパイプを入れることはできません . pgrep を使用することもお勧めします ps の出力を解析しようとするよりも :

count=0
while [ "$count" -lt 10 ] && pgrep relayevent.sh >/dev/null; then
    sleep 3
    count=$(( count + 1 ))
done

BSD システムは pgrep -q ... を使用できます pgrep ... >/dev/null の代わりに pgrep の実際の出力を破棄する 、通常の grep と同様 (終了ステータスのみに関心があります)。

pgrep を入れていないことに注意してください [ ... ] 内のコマンド .これは、出力には関心がなく、終了ステータスのみに関心があるためです。 [ ... ] で 通常、文字列または数値を比較します。 [ ... ] pgrep のように、ゼロ (true) または非ゼロ (false) の終了ステータスになります。

ただし、これはロック メカニズムをチェックするのではなく、特定のプロセスが実行されているかどうかのみをチェックします。

実行中のスクリプトのインスタンスを 1 つだけ取得しようとしている場合は、次のようにすることをお勧めします (EXIT トラップは、スクリプトが正常に終了するたびに実行されます):

lockdir=dir.lock

if mkdir "$lockdir"; then
    trap 'rmdir "$lockdir"' EXIT
else
    echo 'Only one instance of this script allowed' >&2
    exit 1
fi

試行回数とスリープ:

lockdir=dir.lock

count=0
while [ "$count" -lt 10 ]; then
    if mkdir "$lockdir"; then
        trap 'rmdir "$lockdir"' EXIT
        break
    else
        echo 'Locked. Sleeping...' >&2
        sleep 3
    fi

    count=$(( count + 1 ))
done

if [ "$count" -eq 10 ]; then
    echo 'Giving up.' >&2
    exit 1
fi

関連:

  • bash スクリプトのインスタンスが 1 つだけ実行されるようにする方法

Linux
  1. ループに巻き込まれましたか? Awk While、Do While、For ループ、Break、Continue、Exit の例

  2. シェルスクリプトの現在のディレクトリ?

  3. 期待されるシェルスクリプトで生成されたプロセスの終了コードを取得するには?

  1. 2 番目の要素から for ループを開始する - シェル スクリプト

  2. printfを使用しているときに、シェルスクリプトで特殊文字をエスケープする方法は?

  3. Pythonスクリプトからシェルスクリプトへの戻り値

  1. 実行時にスクリプトでシェルを決定しますか?

  2. ソースシェルスクリプトへのパスを決定しますか?

  3. 終了したサブコマンドにパイプするときに bash while ループが終了しないのはなぜですか?