bash函数内判断命令执行结果并返回
需求背景
在bash编程中,经常会需要执行对命令的结果判断,如果正确继续执行,如果不正确则返回。
function foo() {
run_a_cmd
if [ $? -ne 0 ]; then
echo "ERROR: ..."
return 1
fi
}
这是一个标准的流程;
现在遇到的问题是,对函数内的每一个语句都需要判断,都需呀重复上述4条语句;当函数的语句很多时,命令就闲的很冗余。
function foo() {
run_a_cmd
if [ $? -ne 0 ]; then
echo "ERROR: ..."
return 1
fi
run_b_cmd
if [ $? -ne 0 ]; then
echo "ERROR: ..."
return 1
fi
run_c_cmd
if [ $? -ne 0 ]; then
echo "ERROR: ..."
return 1
fi
}
能不能简化一下判断的4条语句呢。
bash的expand_aliases可以用来解决这个问题。
expand_aliases用法
#!/bin/bash
shopt -s expand_aliases
alias CHECKRETURN='{
ret=${?}
if [ ${ret} -ne 0 ]; then
read errmsg
echo ${errmsg}
return ${ret}
fi
}<<
function foo() {
run_a_cmd
CHECKRETURN "ERROR: ..."
run_b_cmd
CHECKRETURN "ERROR: ..."
run_c_cmd
CHECKRETURN "ERROR: ..."
}
这里CHECKRETURN的作用是判断前一条命令的返回值是否为0
如果是0,则什么也不做
如果非0,则打印错误信息,并返回。
注意这里的CHECKRETURN是一个alias,不是一个函数,在shell执行是会展开,否则它里面的return语句将会是从CHECKRETURN返回,而不是从函数foo返回了。
遗憾的是CHECKRETURN只能带一个参数,不能是两个及以上参数;理想的定义是:
CHECKRETURN {RETVAL} "{ERRMESSAGE}"
即指定一个数字返回值,然后打印出错误信息;但是确实不支持也没有办法;不过一个折中的办法虽然很难看,但也能凑合用,就是把{RETVAL}写到"{ERRMESSAGE}",即"{RETVAL} {ERRMESSAGE}",也就是假装还是一个参数,然后在RETURN里面分析这一个参数,取出第一个字段作为{RETVAL},剩下的作为{ERRMESSAGE}。
alias RETURN='{
ret=${?}
if [ ${ret} -ne 0 ]; then
read retp errmsg
echo "${errmsg}"
return ${retp}
fi
}<<
然后调用折用法:
run_a_cmd
CHECKRETURN "12 ERROR: ..."
run_b_cmd
CHECKRETURN "13 ERROR: ..."
run_c_cmd
CHECKRETURN "14 ERROR: ..."
即,如果run_a_cmd失败则返回12,run_b_cmd失败则返回13,run_c_cmd失败则返回14。