エラーは、最初の [ を削除する必要があることです 終了ステータスを確認したいので、コマンドを直接使用してください。
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 つだけ実行されるようにする方法