证明如下:Bash 4
Prompt> $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/')
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0
Prompt> echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/'
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0
Output> 0
Output> 123
Output> 0
命令替换是否不被视为在前台 shell 中运行?这是我的猜测。
答案1
因为命令替换是在子shell中运行的,所以它没有改变PIPESTATUS
父shell的变量。从命令执行环境文档:
命令替换、用括号分组的命令和异步命令在与 shell 环境重复的子 shell 环境中调用,不同之处在于 shell 捕获的陷阱将重置为 shell 在调用时从其父 shell 继承的值。作为管道一部分调用的内置命令也在子 shell 环境中执行。对子 shell 环境所做的更改不会影响 shell 的执行环境。
PIPESTATUS
如果在子 shell 中检查变量,可以获得预期的结果:
$ printf '%s\n' $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/';
for i in ${PIPESTATUS[@]}; do echo $i;done)
0
0
123
0