他人に返信とても良い質問私は次のように主張します。
POSIX仕様を読んでみると、どちらかを使用する構文解析の観点と違いはありません。
POSIX 指定&&||
リストは次のとおりです。複合コマンドこれは、設定された単純なコマンドを実行する前にリスト全体を読み、解析する必要があることを意味します。 POSIXはまたコマンドを指定します拡張は許可されていません||OR
終了ステータスがゼロの別のコマンドに従う場合。予約語の後に続くコマンドが&&||
別のコマンドに簡単にグループ化できると思われる場合、{ command || ( command ; list) ; }
またはリストの各ブランチを&&||
独自に作成してください。複合コマンド。
ただし、POSIXはまた、if...;then...;else...fi
構成の各ブランチに固有の属性があることを指定します。複合コマンドだから:
if compound-list
then
compound-list
[elif compound-list
then
compound-list] ...
[else
compound-list]
fi
これ
if
化合物一覧exit
状態が0の場合は実行する必要があります。then
化合物一覧実行され、コマンドが完了します。
then...
else...
orの後の文字列と予約語の後の文字列をにするのがこの仕様である。複合コマンドそれ自体だけでなく簡単なコマンドこれは、シェルのパーサーが正しく機能するためにコマンドと区切り文字を表す必要があることを意味します。
したがって、基本的にthen ' '
同じ理由で動作しません。
function()
sh: line 2: syntax error: unexpected end of file
...いいえ - それは言うことはできません。
わかりました...
[ -e doesntexist ] && $((i=1)) ; echo $i
\n
...私の答えで指摘された仕様のため、すべての副作用が短絡され、1つのewlineのみが生成されます。結果は...
if [ -e doesntexist ]
then $((i=1))
fi
echo $i
… …それは同じです。
ところが正直に私がif...fi
使用をほとんどしなかったので何か間違って読んだのかよく分からないので説明が間違っているというコメントが走ったり、追加的に気になる点があればただ聞いてみたりします。回答を削除し、次の質問に置き換えました。私はどのように間違っていますか?どう違いますか?
答え1
単純な場合のみ sum で&&
表現できます||
。このif
構造はより一般的です。 (必要に応じてブロックを区切るために中かっこを正しく使用すると仮定します)if CONDITION; then FOO; fi
同じですが、一度(または)が発生すると、通常は不可能です。CONDITION && FOO
else
elif
if CONDITION; then FOO; else BAR; fi
等しくない
CONDITION && FOO || BAR
trueの場合、CONDITION
両方の構成が実行されますFOO
。FOO
falseの場合、if
生成はスキップされ、BAR
生成&& … ||
が実行されますBAR
。
いいえ、この問題を解決するためにこれを使用することはできませんCONDITION && { FOO; true; } || BAR
。これにより、複合コマンドがこの場合、trueの場合はtrueを返し、CONDITION
falseを返します。FOO
if CONDITION; then FOO; else BAR; fi
これは意味の違いです。また、読みやすさもあります。&&
ネストされた使用により、||
迅速に復号化が困難になります。実際、同じコマンドでこれら2つの演算子を使用することはお勧めできません。特に、両方の演算子はシェルで同じ優先順位を持っていますが、CとPerlとRubyを含む他のほとんどのC言語では優先順位が異なることを考えるとさらにそうです。
答え2
if testlist; then else ...fi
そしてtestlist && thenlist || elselist
一般的に言えば、それらは同じではありません。違いは、構成時とそのうちのif
1つだけが実行されることです。それ以外の場合は、終了コードによって異なり、ブロックされる可能性があります。thenlist
elselist
thenlist
eliflist
true
したがって、リストが実行されるテストリストと同じ終了コードを持つように選択した結果リストの最後に追加する必要があります。
if true; then
echo true
test -e doesntexist
else
echo false
fi
これは、コードブロックの終了コードを決定することで無視できます&&
。||
変える
true && { echo true; test -e doesntexist; } || echo false
あなたはする必要があります
true && { echo true; test -e doesntexist; true; } || echo false
一生
if test -e exists; then
echo true
elif test -e doesntexist
echo elif
else
echo false
fi
〜する
test -e exists && { echo true; true; } ||
{ test -e doesntexist && { echo elif; true; } || echo false; }