我在bash(4.2.25(1)版本)中发现了以下结果:

$ 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被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

07-24 14:30