使用するシェルスクリプトでこのエラーが発生し続けます。
$ ./script.sh: line 2: [: missing `]'
grep: ]: No such file or directory
この行は、特定のプロセスがファイルをロックすることを確認するセクションの一部です。
COUNTER=0
while [ ps aux | grep "[r]elayevent.sh" ] && [ "$COUNTER" -lt 10 ]; do
sleep 3
let COUNTER+=1
done
明らかに、私は角括弧がすべて正しく対になっていることを確認しました。これは私にとっては大丈夫に見えます。また、条件付き質問の周りの一般的なスペースは適用されません。
私がここで何を見逃しているのでしょうか?
答え1
エラーは、[
終了状態を確認した後、命令を直接使用したいので、まず削除する必要があることです。
ウィキページ住宅検査ツールこれについての説明があります(問題SC1014):
[ .. ]
if
ステートメントなどのシェル構文の一部ではありません。 Cに似た言語では、括弧と同じではなく、if (foo) { bar; }
テストするコマンドを束ねてはいけません。
[
whoami
orのような一般的なコマンドgrep
ですが、面白い名前があります(参照ls -l /bin/[
)。の略ですtest
。コマンドの終了状態を確認するには、そのコマンドを直接使用します。
コマンドの出力を確認するには、文字列比較のためにまたは/を
"$(..)"
使用して出力を取得します。test
[
[[
また、ps aux | grep -q "[r]elayevent.sh"
これを使用するとstdout
。
pgrep
またはその出力を使用して/dev/null
。
最後のケースではより効率的であるため、最初の条件を最初に使用してください。
したがって、最終スクリプトは次のようになります。
#!/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
答え2
その中にチューブがありません[ ... ]
。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
コマンドを入れない理由[ ... ]
は、出力には興味がなく、終了状態にのみ興味があるからです。[ ... ]
通常、文字列または数字を比較します。これは[ ... ]
実行と同様に終了状態が0(true)または0ではない(false)になりますpgrep
。
ただし、これはロックメカニズムをチェックせず、特定のプロセスが実行されているかどうかを確認します。
スクリプトの単一インスタンスのみを実行する場合は、次のことをお勧めします(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
関連: