回答:
はい、bashでは括弧を使用できます。
(A && B || C) | D
これにより、の出力A && B || C
がにパイプされD
ます。
sh
:)で括弧を使用することもできます
A
サブシェルの内部にあるため、これも含まれA
ます。)
あなたはこれを次のように書くことができます
if A; then B; else C; fi | D
B
またはのいずれかを実行したいと言いますC
が、それをA && B || C
達成しません。IfはA
成功しますが、B
実行され、失敗し、それが実行しますC
。
注1:何らかの形でB
常に成功することを保証でき、短いバージョンに固執したい場合は、引き続き選択します
{ A && B || C; } | D
over ( ... )
は、後者が不必要に新しいサブシェルを強制的に作成するため、最適化されない場合があります。
注2:どちらの形式A
も出力を生成しないと仮定しています。これは例では正しいですが、必ずしもそうであるとは限りません。それは回避することができます
A; if [ "$?" -eq 0 ]; then B; else C; fi | D
{ … }
パイプに起因して、作成するサブシェルを強制しないのですか?私は次の動作を観察します:pgrep bash
and pgrep bash | cat
およびif true; then pgrep bash; fi
and { pgrep bash; }
one line of output; ( pgrep bash; )
and ( pgrep bash; ) | cat
および{ pgrep bash; } | cat
andにif true; then pgrep bash; fi | cat
は2行の出力があります。
... | ...
はサブシェルを作成しますが、これは避けられません。( ... )
、少なくとも理論的には、回避する追加のサブシェルが作成され{ ...; }
ますが、それは私が「最適化されない可能性があるかどうか」を意味します:この特定のケースでは、シェルはそれが重要ではないと認識する可能性があります効果は同じです。
アクセプタ答えは正しいですが、それはして潜在的なユースケースをカバーしていないではないの出力持ちA
の入力としてをD
。それを実現するには、必要にA
応じてストリームのリダイレクトが必要になります。
A
とにかく出力を破棄したい場合:
{ A >/dev/null && B || C; } | D
A
端末での出力を表示する場合:
{ A >/dev/tty && B || C; } | D
A
後続のコマンドの入力としての出力がE
必要な場合は、追加のコマンドグループとストリームリダイレクトが必要になります。
{ { A >&3 && B || C; } | D; } 3>&1 | E
これらすべてがあなたにとってあまりにも難解に見える場合(私にとってはそうです)、終了ステータスに特別なシェル変数を使用し、それを操作することをお勧めしますA
。
A
if [ $? -eq 0 ]; then
B
else
C
fi |
D
もっと簡潔にしたいが、あまりにも難解ではない場合は、これをお勧めします:
A; { [ $? -eq 0 ] && B || C; } | D
(hvdの回答の最後の部分も参照してください。これは、元の回答を書いたときに気づかなかったものです。)
A
パイプラインから移動しました。
A && (B || C) | D
、あなたはAに障害が発生した場合、B、C、またはDを実行しない場合