意思決定構造について学んでいますが、次のコードを見つけました。
if [ -f ./myfile ]
then
cat ./myfile
else
cat /home/user/myfile
fi
[ -f ./myfile ] &&
cat ./myfile ||
cat /home/user/myfile
どちらも同じように振る舞います。ある方法を他の方法よりも使用すると、どのような利点がありますか?
答え1
ほとんどの人はフォーマットを理解する方が簡単だと思いますif
。then
else
fi
の場合はtrueが返されることをa && b || c
確認する必要があります。b
これは微妙なエラーの原因であり、このスタイルを避けるべき理由です。b が true を返さない場合、同じではありません。
$ if true; then false ; else echo boom ; fi
$ true && false || echo boom
boom
長さが短くなることは、非常に短いテストとelse句のない作業に適しています。
die(){ printf "%s: %s\n" "$0" "$*" >&2 ; exit 1; }
[ "$#" -eq 2] || die "Needs 2 arguments, input and output"
if [ "$#" -ne 2 ] ; then
die "Needs 2 arguments, input and output"
fi
&&
そして||
そうです。short circuiting operators
結果がわかったら、不要な追加テストはスキップされます。a && b || c
にグループ化されます(a && b) || c
。終了ステータス0を返さないように定義されている場合a
、fails
グループは既知のものであるため、実行する必要はありません。式の結果がわからないため、実行が必要です。成功すると(0を返す)、演算子はまだ結果がわからないため、調べるために実行する必要があります。成功すれば成功し、結果全体が成功したことが知られているので、実行する必要はありません。失敗すると、式の値がまだわからないため、実行する必要があります。(a && b)
fail
b
||
c
a
&&
a && b
b
b
a && b
||
c
b
||
c
答え2
いいえ、構造if A; then B; else C; fi
はA && B || C
はい。等しくない。
を使用すると、if A; then B; else C; fi
コマンドは常に評価され実行されますA
(少なくとも実行を試みた場合)。その後、コマンドB
またはコマンドが評価され実行されます。C
A && B || C
コマンドの場合は同じですA
が異なります。次の場合、B
コマンドは評価され実行されます。C
C
誰でも A
失敗するまたは B
失敗する。
あなたの例であなたを想定すると、成功chmod u-r ./myfile
にもかかわらず[ -f ./myfile ]
cat /home/user/myfile
私のアドバイス:読みやすく理解しやすく、問題のない必要なものを使用またはA && B
使用してください。A || B
ただし、if...then...else...thenを意味する場合は、を使用してくださいif A; then B; else C; fi
。
答え3
オペレーター&&前のコマンドが正常に実行されたら、次のコマンドを実行します(終了コード($?)0 =論理trueを返します)。
フォームA && B || C
、コマンド(または条件)ㅏ評価され、ㅏ返品本物(成功、終了コード0) 次のコマンド第二処刑される。もしㅏ失敗(それで返されます)間違った- ゼロ以外の終了コード)および/または第二失敗(返品間違った) 次にコマンド氏実行されます。
演算子は次のよう&&
に使用されます。そして条件チェックと演算子は||
次のように動作します。または状態確認中です。
スクリプトで実行したい操作に応じて、A && B || C
フォームを条件付きチェック(例など)に使用したり、コマンドをリンクしたり、前のコマンドに成功した終了コードがある場合は、一連のコマンドを実行したりできます。0。
そのため、次のコマンドを頻繁に表示できます
do_something && do_something_else_that_depended_on_something
。
例:
apt-get update && apt-get upgrade
アップデートが失敗した場合、アップグレードは実行されません(実際の環境では話します...)。
mkdir test && echo "Something" > test/file
echo "Something"
このセクションは成功し、ジョブが終了コードを返した場合にのみ実行されます。mkdir test
0。
./configure --prefix=/usr && make && sudo make install
通常、必要な依存関係コマンドを一緒にリンクしてジョブをコンパイルするときに検出されます。
上記の「チェーン」を使って達成しようとするともし-それから-その他単純な作業では、より多くのコマンドとチェックが必要になります(したがって、書き込む必要があるコードも多くなり、間違っている可能性があります)。
また、リンクされたコマンドを覚えておいてください。&&そして||シェルに基づいて左から右に読みます。次のステップが以前のコマンドの一部の出力に依存するように、コマンドと条件付きチェックを角括弧でグループ化できます。たとえば、次のように見てください。
root@debian:$ true || true && false;echo $?
1
#read from left to right
#true OR true=true AND false = false = exit code 1=not success
root@debian:$ true || (true && false);echo $?
0
# true OR (true AND false)=true OR false = true = exit code 0 = success
または実際の例は次のとおりです。
root@debian:$ a=1;b=1;c=1;[[ $a -eq 1 ]] || [[ $b -eq 1 ]] && [[ $c -eq 2 ]];echo $?
1
#condition $a = true OR condition b = true AND condition $c = false
#=> yields false as read from left to right, thus exit code=1 = not ok
root@debian:$ a=1;b=1;c=1;[[ $a -eq 1 ]] || [[ $b -eq 1 && $c -eq 2 ]];echo $?
0
#vars b and c are checked in a group which returns false,
#condition check of var a returns true, thus true OR false yields true = exit code 0
一部のコマンドは、実行されているプロセスによって異なる終了コードを返すか、その操作に応じて別のコードを返します(たとえば、GNUコマンドはdiff
次を返します)。12つのファイルが異なる場合0そうでない場合)。これらのコマンドは慎重に取り扱う必要があります。&&そして||。
また、パズルのすべての部分を1つに合わせるには、演算子を使用してコマンドをリンクすることに注意してください;
。フォーマットを使用すると、A;B;C
コマンドと終了コードに関係なく、すべてのコマンドが実行され続けます。A
B
答え4
これについてのほとんどの混乱は、おそらくbashドキュメントで次を呼び出すという事実によるものです。ANDとORのリスト。角かっこ内の角かっこ&&
と論理的に似ていますが、||
機能は異なります。
いくつかの例がこれを最もよく説明しています。
注:単一および二重角括弧(
[ ... ]
および[[ ... ]]
)自体は、比較を実行して終了コードを返すコマンドです。彼らは実際には必要はありませんif
。
cmda && cmdb || cmdc
cmda
true で終了するとcmdb
実行されます。
cmda
出口が false の場合、実行されずにcmdb
実行cmdc
されます。
cmda; cmdb && cmdc || cmdd
終了方法はcmda
無視されます。
cmdb
true で終了するとcmdc
実行されます。
cmdb
シャットダウンがfalseの場合、実行されずにcmdc
実行cmdd
されます。
cmda && cmdb; cmdc
cmda
trueで終了したらcmdb
実行してから実行しますcmdc
。
終了がcmda
偽の場合はcmdb
実行しないしかしcmdc
、。
ああ?彼はなぜcmdc
処刑されたのですか?
インタプリタにはセミコロン( ;
)と改行文字がまったく同じ意味を持つからです。 Bashはこのコード行を次のように扱います。
cmda && cmdb
cmdc
cmdb; cmdc
目的の効果を得るには、中かっこで囲む必要があります。複合命令(グループ命令)。追加の終了セミコロンは{ ...; }
構文要件にすぎません。だから私たちは...
cmda && { cmdb; cmdc; }
cmda
trueで終了したらcmdb
実行してから実行しますcmdc
。
cmda
出口が false の場合、cmdb
または両方はcmdc
実行されません。
実行は次の行まで続きます。
使用法
条件付きコマンドのリストは、関数ができるだけ早く返すのに最も便利であるため、解釈および実行する必要のある不要なコードを多く防ぐことができます。ただし、複数の関数を返すことは、すべての可能な条件をより簡単に処理できるように、関数を短く保つように努力する必要があることを意味します。
以下はコード実行の例です。
fnInit () {
:
_fn="$1"
### fnInit "${FUNCNAME}" ...
### first argument MUST be name of the calling function
#
[[ "$2" == "--help-all" ]] && { helpAll ; return 0; }
### pick from list of functions
#
[[ "$2" == "--note-all" ]] && { noteAll ; return 0; }
### pick from notes in METAFILE
#
[[ "$2" == "--version" ]] && { versionShow "${_fn}" "${@:3}"; return 0; }
#
[[ "$2" == "--function" ]] && {
isFnLoaded "$3" && { "${@:3}" ; return 0; }
#
errorShow functionnotfound "Unknown function: $3"
return 0
}
### call any loaded function
#
[[ "$2" == "--help" || "$2" == "-h" ]] && { noteShow "$_fn" "${@:3}"; return 0; }
### fnInit "${FUNCNAME}" --help or -h
#
return 1
}