在某些bash脚本中,我不想set -e
。所以我写了像
var=$(false) || { echo 'var failed!' 1>&2 ; exit 1 ; }
将打印var failed!
。
但是使用declare
时,永远不会使用||
。
declare var=$(false) || { echo 'var failed!' 1>&2 ; exit 1 ; }
那将不打印var failed!
。
所以我来使用
declare var=$(false)
[ -z "${var}" ] || { echo 'var failed!' 1>&2 ; exit 1 ; }
是否有人知道如何将不完美的解决方案两行变成整齐的一行?
换句话说,是否有一个bash成语使declare var
失败更整洁?
这似乎是bash declare
设计中的一个不幸的错误。
答案 0 :(得分:2)
首先,两行与一行的问题可以通过一个叫做分号先生的小东西来解决(另请注意&&
与||
;非常确定你的意思是前者):
declare var=$(false); [ -z "${var}" ] && { echo 'var failed!' 1>&2 ; exit 1 ; }
但我认为你正在寻找一种更好的检测错误的方法。问题是declare
总是根据它是否成功解析其选项并执行赋值返回错误代码。您尝试检测的错误是在命令替换中,因此它超出了declare
的返回代码设计的范围。因此,我不认为使用declare
在RHS上使用命令替换可以解决您的问题。 (实际上你可以做一些麻烦的事情,比如从命令替换中将错误信息重定向到一个平面文件并从主代码中读回来,但是没有。)
相反,我建议在从命令替换中分配它们之前声明所有变量。在初始声明中,您可以根据需要指定默认值。这就是我通常做这种事情的方式:
declare -i rc=-1;
declare s='';
declare -i i=-1;
declare -a a=();
s=$(give me a string); rc=$?; if [[ $rc -ne 0 ]]; then echo "s [$rc]." >&2; exit 1; fi;
i=$(give me a number); rc=$?; if [[ $rc -ne 0 ]]; then echo "i [$rc]." >&2; exit 1; fi;
a=($(gimme an array)); rc=$?; if [[ $rc -ne 0 ]]; then echo "a [$rc]." >&2; exit 1; fi;
编辑好的,我想到的东西接近你想要的东西,但是如果做得好,它需要是两个陈述,而且它很难看,虽然在某种程度上很优雅。它只有在你想要分配的值没有空格或glob(路径名扩展)字符时才有效,这使得它非常有限。
解决方案涉及将变量声明为数组,并使用命令替换打印两个单词,第一个是您要分配的实际值,第二个是命令替换的返回代码。然后你可以检查索引1(除$?
之外,它仍可用于检查实际declare
调用是否成功,尽管这不应该失败),如果成功,则使用索引0,优雅地可以直接作为普通的非数组变量访问:
declare -a y=($(echo value-for-y; false; echo $?;)); [[ $? -ne 0 || ${y[1]} -ne 0 ]] && { echo 'error!'; exit 1; }; ## fails, exits
## error!
declare -a y=($(echo value-for-y; true; echo $?;)); [[ $? -ne 0 || ${y[1]} -ne 0 ]] && { echo 'error!'; exit 1; }; ## succeeds
echo $y;
## value-for-y
我认为你不能比这更好。我仍然推荐我的原始解决方案:与命令替换+赋值分开声明。