`;` と `&&` と `|` には違いがありますか?

`;` と `&&` と `|` には違いがありますか?

複数のコマンドを実行したい場合は;&&と を使用することができます。|

このように: killall Finder; killall SystemUIServercd ~/Desktop/ && rm Cachesまたは:man grep | man catたとえば。

しかし、と|の間には違いがあるのでしょうか? もしあるなら、その違いは何でしょうか?;&&

答え1

  • ;: で区切られたコマンドは; 順番に実行されます。シェルは各コマンドが終了するまで順番に待機します。

  • &&: コマンド after は、コマンド beforeが終了ステータス 0 を返した&&場合にのみ実行されます。これは演算子と考えることができます。&&AND

  • |: パイプ。式では、command1 | command2コマンド1の標準出力はパイプを介してコマンド2の標準入力に接続されます。

言及する価値のある同様の制御演算子が他にもあります。

  • ||: 後のコマンドは、前のコマンドがゼロ以外の終了ステータスを返した||場合にのみ実行されます。これは演算子と考えることができます。 とはまったく異なるものであることに注意してください。||OR|||

  • &: シェルは によって終了されたコマンドを&バックグラウンドで実行し、コマンドの終了を待たずに、直ちに終了コード 0 を返します。 繰り返しますが、 は とは&何の関係もありません&&

  • |&: 省略形。つまり2>&1 |、コマンド 1 の標準出力と標準エラーの両方がパイプを介してコマンド 2 の標準入力に接続されます。

さらに、 を使用する場合は、または をzsh使用してコマンドを開始することもできます。この場合、ジョブは直ちに放棄され、起動後にジョブ テーブル内に場所がなくなります。&|&!

答え2

Aと という2つのコマンドを考えてみましょうB

A | B

Aと はB並列に実行され、 の標準出力Aは の標準入力として送信されますB

書くとき

A; B

Aが実行され、次にBが実行されます (set -eが使用され、Aゼロ以外の終了ステータスで終了しない限り、その場合、シェルは の直後に終了しますA)。

書くとき

A && B

Aが実行され、正常に終了したB場合(終了ステータスがゼロ)にのみ実行されますA。この形式は、例えば

cd some_dir && rm file*

&&、正しいファイルが削除されることを確認します。つまり、 がcd成功した場合にのみファイルが削除されます。

答え3

他の回答ではすでに|&&およびについて説明されている;ので、明示的に求められていないことをさらに追加します||

A || B

Aが実行され、失敗したB場合にのみ実行されますA。これはエラー条件に対応する場合に便利です。

martin@martin ~ % rm doesnotexist 2>/dev/null || echo "failed to delete file"
failed to delete file

(は自身2>/dev/nullのエラーメッセージを非表示にするために必要ですrm。)

答え4

実際の例を考えると、それぞれを使用する理由を説明している人は誰もいないようです。試してみます:

killall Finder; killall SystemUIServer

のようなコマンドはkillall実行に時間がかかることがあります。セミコロンを使用すると、両方のコマンドを一度に実行し、待っている間に他の作業を行うことができます。そうすれば、2 回 (コマンドごとに 1 回) 待つ必要がなくなります。

cd ~/Desktop/ && rm Caches

ディレクトリを削除して~/Desktop/Caches、ディレクトリ に移動したい~/Desktopと考えています。現在のディレクトリからディレクトリ Caches を削除することは避けてください (変更する前に)。そのため、&&削除コマンドを実行する前に、を使用してディレクトリの変更が成功したことを確認します。

man grep | man cat

これは私には意味が分かりません。このmanコマンドは入力を処理しないので、パイプしても何も起こりません。おそらく、

man grep || man cat

これは のマニュアルページを検索しgrep、見つからなければ のマニュアルページを表示しますcat。あるいは、

man grep | cat

catこれは、ページャー (通常は ) ではなく、マニュアル ページを表示するために を使用しますless。は|、 からの出力をmanコマンドcat(すべてを画面にダンプするだけ) にリダイレクトします。これは、less でキーボード コマンドを使用するのではなく、スクロール バーを使用してファイル内を前後に移動できる GUI で役立ちます。

注: より一般的なケースで何をすべきかを知りたい場合は; && | ||、jimmij の回答を参照することをお勧めします。私は質問の例で何が起こっているのかを説明しようとしているだけです。

関連情報