次のコマンドの接続方法の違いは何ですか?
cmd1; cmd2
cmd1 && cmd2
答え1
があるとしますcommand1 && command2
。
この場合、command2
終了ステータス 0 が返された場合にのみ実行が発生します。command1
;
単にコマンドの区切り記号です。したがって、返された内容はすべてcommand2
実行されます。command1
$> [[ "a" = "b" ]] && echo ok
$> [[ "a" = "b" ]]; echo ok
ok
答え2
cmd1; cmd2
実行cmd1
、それからcmd2
何が起こっても。これは、とcmd1
をcmd2
別々の行に置くのとまったく同じです。この複合コマンドの戻り状態はの戻り状態ですcmd2
。
cmd1 && cmd2
Execute cmd1
。そして終了状態がcmd1
0の場合にcmd2
実行します。この複合コマンドの戻り状態は、cmd1
ゼロでない場合(したがって実行されていない場合)、そうでない場合は状態(実行されている場合)をcmd2
返します。cmd2
if cmd1; then cmd2; fi
ほとんどの場合同じですcmd1 && cmd2
。主な違いは、ゼロif
以外の状態が返されると、バージョンがゼロを返すことです。cmd1
このコマンドは成功した場合は0を返し、失敗した場合は0以外のエラーコード(1から255の間、通常より高い値は異なる意味を持つため1から125の間)を返します。したがって、cmd1; cmd2
これは「何があってもこのコマンドを順番に実行する」を意味し、「cmd1 && cmd2
このコマンドを実行しますが、最初のコマンドが失敗した場合はすぐに停止」を意味します。
コマンドシェルを実行して「エラー終了」モードに入りますset -e
。このモードでは、条件構文(&&
orの左側、||
andの条件部分)を除いて、コマンドがゼロ以外の状態を返すたびにシェルが終了します。したがって、under、(またはnewline)は実際に²と同じです。if
while
set -e
;
&&
1制御フローに関する限り、これはすべてです。ニューラインとセミコロンはまったく同じ方法で実行されますが、まったく同じ方法で解析されません。たとえば、パーサーがエイリアス定義を実行する前にエイリアスチェックを実行するため、これはalias ls=true; ls
実行ls
されませんtrue
ls
。 1これは、.egを追加しても優先順位が低いため、同等であるという意味ではありません。また、サブシェルとの相互作用はひどいです。詳細により、この回答は遠すぎます。&&
;
set -e
;
&&
cmd1 && cmd2 || cmd3
set -e; { cmd1; cmd2; } || cmd3
set -e
答え3
最初の行は、最初のコマンドが成功したかどうかに関係なく、コマンドを 1 つずつ実行します。 2行目はシェルロジックの例です。最初のコマンドが成功した場合にのみ2番目のコマンドを実行します。これは&&
論理的だからですand
。したがって、第1の命令が失敗した場合、ライン全体の論理状態が偽であることが知られており、第2の命令を評価する必要はない。
答え4
より現実的には違いがあります。
cd /backup/old; rm -rf -- *
そして
cd /backup/old && rm -rf -- *
。それ以外に、これは愚かなアプローチです。最初の方法は成功または失敗rm
に関係なくcd
実行されるため、ファイルシステム全体(または呼び出し方法に応じて$ HOME)を削除します。