管道 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 的回答当我写下原来的答案时我没有注意到。)

相关内容