B を D にパイプしますか? - A && B || C | D

B を D にパイプしますか? - A && B || C | D

A && B || C | DB または C のいずれかが D にパイプされるようにコマンド構造を書き直す方法はありますか?

現在のコマンドでは、B のみが実行されるか、C と D の両方が実行されます。

例えば:

ここに画像の説明を入力してください

答え1

はい、bash では括弧を使用できます。

(A && B || C) | D

この方法では、 の出力A && B || Cが にパイプされますD

答え2

これは次のように書くことができます

if A; then B; else C; fi | D

Bまたは のいずれかを実行したいとのことですCが、A && B || Cそれが実現されません。Aは成功しても、B実行されて失敗した場合は、 が実行されますC

注1: ​​常に成功することを保証できB、短縮版にこだわりたい場合は、

{ A && B || C; } | D

後者( ... )は、新しいサブシェルを不必要に作成することを強制しますが、これは最適化によって削除される場合と削除されない場合があります。

注2: どちらの形式もA出力を生成しないと仮定していますが、これはあなたの例では当てはまりますが、一般的には必ずしもそうではありません。これは次のように回避できます。

A; if [ "$?" -eq 0 ]; then B; else C; fi | D

答え3

アクセプタの回答は正しいが、潜在的なユースケースをカバーしていない。ないの出力を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の回答最初の回答を書いたときには気づきませんでした。

関連情報