为什么添加| 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
答案 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
则正确地报告了这一点。