回答:
:
内部から終了しなければならないループを書くのに便利です。
while :
do
...stuff...
done
break
またはexit
が呼び出されない限り、またはシェルが終了シグナルを受信しない限り、これは永久に実行されます。
while true; do ...; done
よりも優れたリーダーと通信の意図をwhile :; do ...; done
シェルスクリプトで「unless」ステートメントが必要な場合は、「not」条件を使用します。これは、一部のテストで間抜けに見えるか、true-clauseで「:」を使用し、実際のコードをfalse-句。
if [ some-exotic-condition ]
then
:
else
# Real code here
fi
「エキゾチックな状態」は、否定したくないものである可能性があります。または、「負の論理」を使用しない場合、それははるかに明確になります。
autoconf
デフォルトを追加する方がはるかに簡単であるため、によって生成されたスクリプトにも表示され:
ます。
!
前に貼り付けるの[ some-exotic-condition ]
が間抜けであるかどうかはわかりませんが、: else
間抜けではないので余分です。
!
トークンは、コマンド全体のパイプ要素を否定します。 while ! grep ... ; do ... done
またはif ! [ ... ] ; then ... fi
。基本的にはtest/[]
構文の外部にあります。参照:pubs.opengroup.org/onlinepubs/9699919799/utilities/…–
私が:
役に立つと思う2つのケースがあります:
#!/bin/sh
# set VAR to "default value" if not already set in the environment
: "${VAR=default value}"
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR}"
これは、シェルスクリプトのユーザーがスクリプトを編集せずに設定を上書きできるようにする便利な方法です。(ただし、エクスポートされた環境でユーザーが使用する変数を偶然に持っている場合、予期しない動作のリスクを実行しないため、コマンドライン引数の方が優れています。)ユーザーが設定をオーバーライドする方法は次のとおりです。
VAR="other value" ./script
${VAR=value}
構文はセットに言うVAR
とvalue
あればVAR
、既に設定されていない場合、変数の値に展開されます。変数の値はまだ気にしないので、それ:
を捨てるためにno-opコマンドに引数として渡されます。
にもかかわらず:
、展開はシェルによって行われる(ないノーオペレーションコマンドで:
実行する前に、コマンド!) :
(該当する場合)変数の割り当てが依然として発生してコマンドが。
のtrue
代わりにを使用したり、他のコマンドを使用したりすることもでき:
ますが、意図が明確でないため、コードが読みにくくなります。
次のスクリプトも機能します。
#!/bin/sh
# print the value of the VAR variable. Note that POSIX says the behavior
# of echo is implementation defined if the first argument is '-n' or if any
# argument contains a '\', so use printf instead of echo.
printf '%s\n' "VAR=${VAR=default value}"
しかし、上記の維持ははるかに困難です。を使用する行${VAR}
がそのprintf
行の上に追加された場合、デフォルトの割り当て展開を移動する必要があります。開発者がその割り当てを移動するのを忘れると、バグが発生します。
空の条件ブロックは一般に回避する必要がありますが、役に立つ場合があります。
if some_condition; then
# todo: implement this block of code; for now do nothing.
# the colon below is a no-op to prevent syntax errors
:
fi
空のtrue if
ブロックがあると、テストを無効にするよりもコードが読みやすくなると主張する人もいます。例えば:
if [ -f foo ] && bar || baz; then
:
else
do_something_here
fi
間違いなく読みやすい:
if ! [ -f foo ] || ! bar && ! baz; then
do_something_here
fi
ただし、空の真のブロックよりも優れた代替アプローチがいくつかあると考えています。
関数に条件を入れます:
exotic_condition() { [ -f foo ] && bar || baz; }
if ! exotic_condition; then
do_something_here
fi
否定する前に、条件を中括弧(または括弧、ただし括弧はサブシェルプロセスを生成し、サブシェル内の環境に加えられた変更はサブシェルの外側に表示されません)に入れます。
if ! { [ -f foo ] && bar || baz; } then
do_something_here
fi
の||
代わりに使用if
:
[ -f foo ] && bar || baz || {
do_something_here
}
反応が条件をアサートするような単純なワンライナーである場合、私はこのアプローチを好みます:
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$@"; exit 1; }
[ -f foo ] && bar || baz || fatal "condition not met"