以下示例尝试执行命令并检查它是否已成功执行,同时捕获其输出以进行进一步处理:
#!/bin/bash
readonly OUTPUT=$(foo)
readonly RES=$?
if [[ ${RES} != 0 ]]
then
echo "failed to execute foo"
exit 1
else
echo "foo success: '${OUTPUT}'"
fi
它报告说它是成功的,即使没有这样的foo
可执行文件。但是,如果我从readonly
变量中删除OUTPUT
,则会保留错误的退出代码并检测到失败。
我尝试使用readonly作为"防御性编程"在某处推荐的技术......但在这种情况下它看起来像是咬自己。
是否有一些干净的解决方案来保留readonly
,同时仍然捕获命令/子shell的退出代码?令人失望的是,人们必须记住这种特殊的用例,或者恢复为不使用readonly
......
在Debian Wheezy上使用Bash 4.2.37(1)。
答案 0 :(得分:12)
问题是readonly
是它自己的命令,它返回的退出代码是它自己的退出代码,而不是命令替换的退出代码。
来自help readonly
:
退出状态:
除非给出无效选项或NAME无效,否则返回成功。
因此,您需要使用两个单独的命令:
$ output=$(false)
$ readonly res=$?
$ readonly output
这会保存您想要的退出代码:
$ echo $res
1
缺少entering a debugger,无法取消设置只读变量。因此,除非您希望它在剩余的bash会话中保持不变,否则不要设置readonly变量。
两个readonly
命令可以组合成一个(帽子提示:Chepner):
$ output=$(false)
$ readonly output res=$?
$ echo $res
1
最好使用较低或混合大小写的名称作为变量。系统使用所有大写名称,您不想意外覆盖系统变量。