PIPESTATUS 忽略否定?
PIPESTATUS ignores negation?
我刚刚在 bash(版本 4.2.25(1)-release)中发现了以下结果:
$ true; echo "${PIPESTATUS[@]}"
0
$ ! true; echo "${PIPESTATUS[@]}"
0
$ false; echo "${PIPESTATUS[@]}"
1
$ ! false; echo "${PIPESTATUS[@]}"
1
$ true && false; echo "${PIPESTATUS[@]}"
1
$ true && ! false; echo "${PIPESTATUS[@]}"
1
所以,$PIPESTATUS
似乎在所有情况下都忽略了否定。这是一个已知的问题?我找不到任何相关信息。或者这是通缉行为?如果是这样,背后的原因是什么?
使用子 shell 时,一切如我所料:
$ (true && ! false); echo "${PIPESTATUS[@]}"
0
我认为这种行为是有意,如果用完整的管道查看会变得更清楚:
a | b | c | d ; echo "${PIPESTATUS[@]}"
这将显示进程 a
、b
、c
和 d
.
的退出状态
现在,否定仅适用于完整管道的退出状态:
! a | b | c | d ; echo "${PIPESTATUS[@]}"
不允许对部分管道取反:
a | ! b | c | d # Syntax error at "| !"
因为这种方法,管道关联比否定更强(可以说这是关联级别的! (a | b | c | d)
),所以管道成分的结果不受否定的影响,因为在评估管道后,稍后应用否定。
! a | b | c
被 shell 解释为 !{a | b | c;}
而不是 {! a;} | b | c
。
单个命令退出状态存储在 ${PIPESTATUS[@]}
.
$?
是指整个命令的退出状态,包括!
。
您可以通过实际生成子 shell 来强制 (! a) | b | c
。例如
$ true; echo "${PIPESTATUS[@]}"
0
$ (! true); echo "${PIPESTATUS[@]}"
1
$ false; echo "${PIPESTATUS[@]}"
1
$ (! false); echo "${PIPESTATUS[@]}"
0
我刚刚在 bash(版本 4.2.25(1)-release)中发现了以下结果:
$ true; echo "${PIPESTATUS[@]}"
0
$ ! true; echo "${PIPESTATUS[@]}"
0
$ false; echo "${PIPESTATUS[@]}"
1
$ ! false; echo "${PIPESTATUS[@]}"
1
$ true && false; echo "${PIPESTATUS[@]}"
1
$ true && ! false; echo "${PIPESTATUS[@]}"
1
所以,$PIPESTATUS
似乎在所有情况下都忽略了否定。这是一个已知的问题?我找不到任何相关信息。或者这是通缉行为?如果是这样,背后的原因是什么?
使用子 shell 时,一切如我所料:
$ (true && ! false); echo "${PIPESTATUS[@]}"
0
我认为这种行为是有意,如果用完整的管道查看会变得更清楚:
a | b | c | d ; echo "${PIPESTATUS[@]}"
这将显示进程 a
、b
、c
和 d
.
现在,否定仅适用于完整管道的退出状态:
! a | b | c | d ; echo "${PIPESTATUS[@]}"
不允许对部分管道取反:
a | ! b | c | d # Syntax error at "| !"
因为这种方法,管道关联比否定更强(可以说这是关联级别的! (a | b | c | d)
),所以管道成分的结果不受否定的影响,因为在评估管道后,稍后应用否定。
! a | b | c
被 shell 解释为 !{a | b | c;}
而不是 {! a;} | b | c
。
单个命令退出状态存储在 ${PIPESTATUS[@]}
.
$?
是指整个命令的退出状态,包括!
。
您可以通过实际生成子 shell 来强制 (! a) | b | c
。例如
$ true; echo "${PIPESTATUS[@]}"
0
$ (! true); echo "${PIPESTATUS[@]}"
1
$ false; echo "${PIPESTATUS[@]}"
1
$ (! false); echo "${PIPESTATUS[@]}"
0