管道 B 到 D? - A && B || C | D

管道 B 到 D? - A && B || C | D

有沒有辦法重寫命令結構A && B || C | D,以便將 B 或 C 透過管道傳輸到 D 中?

使用當前命令,要么僅運行 B,要么運行 C 和 D。

例如:

在此輸入影像描述

答案1

是的,在 bash 中你可以使用括號:

(A && B || C) | D

這樣 的輸出A && B || C將透過管道傳送到D.

答案2

你可以把它寫成

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

你說你想運行Bor C,但A && B || C沒有實現。如果A成功,但B運行失敗,則會執行C.

註 1:如果你能以某種方式保證總是B成功並且想要堅持使用簡短版本,那麼我仍然會選擇

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

( ... )因為後者不必要地強制創建一個新的子 shell,這可能會也可能不會被優化掉。

註 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
    

如果這一切對你來說太神秘了(就像對我來說),我建議你使用特殊的 shell 變數作為退出狀態A並使用它:

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

如果你想更簡潔但又不想太晦澀,我建議這樣:

A; { [ $? -eq 0 ] && B || C; } | D

(另見最後一部分hvd 的回答當我寫下原來的答案時我沒有註意到。

相關內容