将多个命令传递到单个命令中

Rob*_*ark 54 bash shell pipe process subshell

如何将多个命令的stdout传递给单个命令?

示例1:组合并排序所有三个echo命令的输出:

echo zzz; echo aaa; echo kkk
Run Code Online (Sandbox Code Playgroud)

期望的输出:

aaa
kkk
zzz
Run Code Online (Sandbox Code Playgroud)

示例2:重写以下内容,以便所有命令都使用管道在单个命令行中,而不重定向到临时文件:

setopt > /tmp/foo; unsetopt >> /tmp/foo; set >> /tmp/foo; sort /tmp/foo
Run Code Online (Sandbox Code Playgroud)

Rob*_*ark 89

使用括号()将命令组合到一个进程中,该进程将连接每个进程的stdout.

示例1(注意这$是shell提示符):

$ (echo zzz; echo aaa; echo kkk) | sort
aaa
kkk
zzz
Run Code Online (Sandbox Code Playgroud)


例2:

(setopt; unsetopt; set) | sort
Run Code Online (Sandbox Code Playgroud)

  • +1.您也可以使用不会产生子shell的大括号.语法有点严格:`{setopt; unsetopt; 组; } | 排序| less` - 括号周围的空白区域和后面的分号是必需的. (14认同)
  • @glenn:无所谓(在bash 3.2.48中测试),因为管道强制它进入子shell. (8认同)
  • @KennyEvitt检查[管道部分](https://www.gnu.org/software/bash/manual/bash.html#Pipelines):"管道中的每个命令都在自己的子shell中执行......".实际上,这可以通过[`shopt -s lastpipe`](https://www.gnu.org/software/bash/manual/bash.html#The-Shopt-Builtin)更改,它运行*last*部分当前shell中的管道.但在这种情况下,它是我们关注的第一部分,所以它仍然在子shell中运行. (3认同)
  • @KennyEvitt它似乎将它们合并到单个级别的子shell中(至少在bash下,测试w /版本2.05b.0,3.2.57和4.2.10;其他shell可能不同).但是当我使用`{(echo zzz; echo aaa; echo kkk)} |时 sort`我确实得到了额外的子shell. (3认同)
  • 应该注意的是`$`是提示符,而不是命令的一部分 (2认同)

cod*_*ter 14

你可以使用{}这个,并消除对子shell的需求(list),如下所示:

{ echo zzz; echo aaa; echo kkk; } | sort
Run Code Online (Sandbox Code Playgroud)

{之前和之后我们确实需要一个空白字符}.;当序列写在一行上时,我们也需要最后一个.

我们也可以在多行上写它而不需要任何;:

例1:

{
  echo zzz
  echo aaa
  echo kkk
} | sort
Run Code Online (Sandbox Code Playgroud)

例2:

{
  setopt
  unsetopt
  set
} | sort
Run Code Online (Sandbox Code Playgroud)