管道中`$?`的正确值是多少?

时间:2015-04-18 12:32:24

标签: bash shell sh zsh ksh

我有点不安地发现以下行为:

bash$ false
bash$ true | echo $?
0
bash$ ksh
ksh$ false
ksh$ true | echo $?
0
ksh$ zsh
zsh$ false
zsh$ true | echo $?
1

直观地说,看起来zsh是正确的,而bash和ksh是错误的。 $?是'最近执行的管道的退出状态',在每种情况下应为1.请注意,false | echo $?kshbash中也会打印0。此时标准是否灵活(即行为未指定),或bashksh不合规?我也很想知道bash和ksh正在做些什么来解决这个问题。

$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin11)
Copyright (C) 2007 Free Software Foundation, Inc.
$ zsh --version
zsh 4.3.11 (i386-apple-darwin11.0)
$ ksh --version
  version         sh (AT&T Research) 1993-12-28 s+

1 个答案:

答案 0 :(得分:4)

POSIX说:

  

$?       扩展到最近[命令或]管道的十进制退出状态...

请注意@lurker的评论。 Bash in it的当前版本4.3.11zsh的行为相同。

bashzsh中发生的事情是$?将在管道之前由命令设置,并且不会在管道内更改。这就是预期结果是来自false - >的返回值的原因1。这就是POSIX指定的内容。

我找不到任何描述ksh行为的文档。我只能假设ksh在执行管道之前重置$?,因为以下代码有效:

#!/bin/ksh
false
ret=$?
true | echo "$ret"

可能这应该作为ksh中的错误提交。但是,我不确定POSIX是否完全指定了这种行为。