为什么使用嵌套命令的存储返回码退出会导致 Dash 和 Bash 中的返回码不同?

Kar*_*ter 8 shell bash dash subshell exit-status

跑步

bash -c 'bash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'
Run Code Online (Sandbox Code Playgroud)

结果test1被打印到控制台并echo $?打印1在我的理解中是正确的,因为命令应该返回内部[b/d]ash -c返回的内容,而

dash -c 'dash -c "echo test1; exit 1;" &> /tmp/x; buildresult=$?; tail -n 100 /tmp/x; exit $buildresult;'
Run Code Online (Sandbox Code Playgroud)

导致相同的输出,但0根据返回echo $?

我想了解这种差异,以拓宽我对 shell 和可移植 shell 编程的理解。

我在 Ubuntu 17.10 (Artful Aardvark) 上使用bash4.4.12 和dash0.5.8-2.3ubuntu1。

Mic*_*mer 20

&>不在 POSIX 中并且不受dash. 它被解析为& >,因此命令改为后台处理。从父级的角度来看,后台命令的退出状态为零,因为在您阅读 $? 时它们还没有退出。

这也是为什么(至少对我而言)在命令完成,“ test1” 输出出现在我的提示中。

Bash 的&> foo等价于> foo 2>&1,可移植的脚本应该使用后者。

  • `&>` 在 POSIX 中。那是 `&` 后跟 `>`。在`foo &> bar`中,`foo &`在后台启动`foo`,`> bar`在没有命令的情况下执行重定向。`bash` 以不同的方式解释它时不符合 POSIX。 (6认同)
  • 有趣的是,https://wiki.ubuntu.com/DashAsBinSh 中没有提到这一点,我冒昧地编辑了该页面并将其包含在内 (4认同)