Bash 命令替换的不同输出

Bash 命令替换的不同输出,bash,process,Bash,Process,为什么添加| wc-l会改变以下结果 tst: #/bin/bash pgrep tst | wc-l echo$(pgrep tst | wc-l) echo$(pgrep tst)| wc-l 甚至 $ bash -x tst + wc -l + pgrep tst 0 ++ pgrep tst ++ wc -l + echo 0 0 ++ pgrep tst + echo 命令替换导致名称中包含tst的附加进程,该进程包含在wc-l的输入中。命令替换导致名称中包含tst的附加进程,它包

为什么添加
| wc-l
会改变以下结果

tst:

#/bin/bash
pgrep tst | wc-l
echo$(pgrep tst | wc-l)
echo$(pgrep tst)| wc-l
甚至

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

命令替换导致名称中包含
tst
的附加进程,该进程包含在
wc-l

的输入中。命令替换导致名称中包含
tst
的附加进程,它包含在
wc-l
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(运行脚本的主shell和为处理管道的
echo
部分而创建的子shell)。它将每一条打印为单独的行,类似于:

11730
11736
命令替换捕捉到了这一点,但由于它不在双引号中,因此它们之间的换行符转换为参数分隔符,因此整个过程相当于:

echo 11730 11736 | wc -l

因此,
echo
将两个ID打印为一行,并且
wc-l
正确地报告了这一点。

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(运行脚本的主shell和为处理管道的
echo
部分而创建的子shell)。它将每一条打印为单独的行,类似于:

11730
11736
命令替换捕捉到了这一点,但由于它不在双引号中,因此它们之间的换行符转换为参数分隔符,因此整个过程相当于:

echo 11730 11736 | wc -l

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

但是为什么第三行只输出一个PID?我稍微修改了上面的代码,使其更简洁。可能是一种优化,因为命令替换导致的shell看到它只需要运行一个命令,所以它不会分叉。但是为什么第三行只吐出一个PID呢?我稍微修改了上面的代码,使其更加简洁。可能是一种优化,因为命令替换导致的shell只需运行一个命令,因此不会分叉。