パイプBからD?-A && B || C | D


14

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

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

例えば:

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

回答:


31

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

(A && B || C) | D

これにより、の出力A && B || CがにパイプされDます。


6
それともA && (B || C) | D、あなたはAに障害が発生した場合、B、C、またはDを実行しない場合
zwol

2
sh:)で括弧を使用することもできます
-EKons

中括弧の代わりに括弧を使用することが意図的な決定であるか(もしそうなら、利点は何か?)または単なる見落としであるかどうかは不明です。説明してもらえますか?
トムフェネク

@TomFenech Parensにより、式はサブシェルで実行されます。サブシェルは、残りのスクリプトのPOVとは(単一の)別のプロセスです。したがって、かっこ内の式の出力が何であれ、一緒にパイプされます。(Aサブシェルの内部にあるため、これも含まれAます。)
jpaugh

1
@jpaugh分離についてのあなたのポイントは良いものだと思いますが、中括弧を使用すると出力は同じようにパイプされますよね?
トムフェネク

14

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

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 bashand pgrep bash | catおよびif true; then pgrep bash; fiand { pgrep bash; }one line of output; ( pgrep bash; )and ( pgrep bash; ) | catおよび{ pgrep bash; } | catandにif true; then pgrep bash; fi | catは2行の出力があります。
-wchargin

@wchargin ... | ...はサブシェルを作成しますが、これは避けられません。( ... )、少なくとも理論的には、回避する追加のサブシェルが作成され{ ...; }ますが、それは私が「最適化されない可能性があるかどうか」を意味します:この特定のケースでは、シェルはそれが重要ではないと認識する可能性があります効果は同じです。
hvd

5

アクセプタ答えは正しいですが、それはして潜在的なユースケースをカバーしていないではないの出力持ち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の回答の最後の部分も参照してください。これは、元の回答を書いたときに気づかなかったものです。)


私の答えはそれをカバーしています。「注2:」に書いたものを参照してください。ここでは、単にAパイプラインから移動しました。
hvd

@hvd:あなたは正解です。あなたの答えのその部分を指摘してくれてありがとう!申し立てを変更し、それに応じてクレジットを提供しました。
デビッドフォースター
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.