我意识到这个事实,但我不知道为什么:
cat abc | echo $?
如果abc
不存在,但上面的命令仍会返回0
。有谁知道关于为什么的理论?
答案 0 :(得分:9)
必须这种方式的原因是管道由同时运行的进程组成。 cat
的退出代码不能作为参数传递给echo
,因为参数在命令开始运行时设置,echo
在cat
之前开始运行1}}已经完成。
echo
没有从标准输入中获取输入,因此管道字符右侧的echo
始终是错误的。
<强>更新强>
既然现在很清楚你是在问一个真正的问题,而不仅仅是误解了你看到的东西,我自己也试过了。我从我尝试过的大多数shell(dash,zsh,pdksh,posh和bash 4.2.37)中得到了我认为正确的结果(1),但是从bash 4.1.10和ksh(版本JM 93u + 2012-02)得到0 -29)。
我认为版本之间bash行为的变化是有意的,4.1.x行为被认为是一个bug。如果你看起来足够努力,你可能会在更新日志中找到它。不知道ksh。
csh和tcsh(用$status
代替$?
)也说0,但我打赌没有人关心这个。
邀请拥有更多shell集合的人进行测试:
for sh in /bin/sh /bin/ksh /bin/bash /bin/zsh ...insert more shells here...; do
echo -n "$sh "
$sh -c 'false;true|echo $?'
done
答案 1 :(得分:4)
它与cat abc
没有任何关系,但是您执行了上一个命令。因此,在执行cat abc | echo $?
时获得的代码告诉您历史记录中的上一个命令是否成功。
来自man bash
:
特殊参数
? - 扩展到最近执行的前台管道的退出状态。
所以当你这样做时:
cat abc | echo $?
echo $?
是指您使用的上一个命令,而不是cat abc
。
$ cat a
hello
$ echo $?
0
$ cat aldsjfaslkdfj
cat: aldsjfaslkdfj: No such file or directory
$ echo $?
1
所以
$ cat a
$ cat a | echo $?
0
$ cat aldsjfaslkdfj
cat: aldsjfaslkdfj: No such file or directory
$ cat a | echo $?
1
答案 2 :(得分:1)
您将'cat abc'的输出传输到'echo $?'这不是你想要的。 您想要回显'cat'的退出代码
cat abc; echo $?
是你想要的。或者,如果可以,只需将其写成两行。
答案 3 :(得分:0)