不同的命令替换输出

时间:2019-07-08 17:08:40

标签: bash process

为什么添加| wc -l会改变结果,如下所示?

tst:

#!/bin/bash
pgrep tst | wc -l
echo $(pgrep tst | wc -l)
echo $(pgrep tst) | wc -l
$ ./tst
1
2
1

甚至

$ bash -x tst
+ wc -l
+ pgrep tst
0
++ pgrep tst
++ wc -l
+ echo 0
0
++ pgrep tst
+ echo

2 个答案:

答案 0 :(得分:1)

命令替换会引发一个附加过程,该过程的名称中包含tst,该过程包含在wc -l的输入中。

答案 1 :(得分:1)

pgrep和子shell可能具有怪异的交互,但是在这种情况下,这只是一条红鲱鱼。实际原因是在命令替换周围缺少双引号:

$ cat tst2
#!/bin/bash
pgrep tst | wc -l
echo "$(pgrep tst | wc -l)"
echo "$(pgrep tst)" | wc -l
$ ./tst2
1
2
2

原始脚本中发生的是命令中的内容

echo $(pgrep tst) | wc -l

pgrep打印两个进程ID(运行脚本的主外壳程序,以及为处理管道的echo部分而创建的子外壳程序)。它将每个单独的行打印出来,就像:

11730
11736

命令替换捕获了这一点,但是由于它不在双引号中,因此它们之间的换行符被转换为参数中断,因此整个过程等效于:

echo 11730 11736 | wc -l

结果,echo将两个ID都打印为一行,而wc -l则正确地报告了这一点。