我是bash的新手,并且遇到一个问题,即在我的脚本中始终调用exit
。考虑一下这个简单的代码:
if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
/export/home/scripts/script1.sh \
"$x" \
|| echo "Error.. something went wrong." && exit 1
fi
如果&&
优先于||
?
使用GNU bash,版本3.2.51(1)。
由于
答案 0 :(得分:4)
你可以这样做:
if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
/export/home/scripts/script1.sh \
"$x" \
|| { echo "Error.. something went wrong." && exit 1 ; }
fi
注意:我使用的是{ ; }
,而不是()
,因为()
会在子shell中打开您的命令,因此它不会退出。
答案 1 :(得分:4)
&&
和||
在shell中具有相同的优先级;隐式括号为(a || b) && c
,而不是a || (b && c)
。将||
和&&
混合在同一个列表中很少是一个好主意;使用明确的if
语句。
if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
if ! /export/home/scripts/script1.sh "$x"; then
echo "Error.. something went wrong"
exit 1
fi
fi
对于算术比较,为了便于阅读,更喜欢arithemetic命令((...))
而不是[[ ... ]]
。
if (( x >= 1 && x <= 4 )); then
答案 2 :(得分:2)
您可以使用大括号重新组合命令,而无需创建新的子shell:
{ true || false; } && echo true || echo false # echoes true
{ false || false; } && echo true || echo false # echoes false
它的语法非常烦人:开括号后面必须跟一个空格(或$IFS
的另一个字符,如换行符或制表符),并且右括号前面必须有换行符或;
,表示块的最后一个命令的结束。
括号没有那些困难,但是它们会在子shell中执行它们的指令,这会产生多种其他效果:
exit
只会退出子shell,而不是运行脚本的shell:(exit)
是无操作a=0;( (( a++ )) ; echo $a) ; echo $a
将从子shell返回1,然后从外壳返回0。答案 3 :(得分:0)
我更喜欢使用if
对脚本进行显式测试,以便在事情变得梨形之后我可以自行清理。有助于保持代码看起来更清晰。
if [[ "$x" -ge 1 && "$x" -le 4 ]]; then
if ! /export/home/scripts/script1.sh "$x"; then
err="Error.. something went wrong."
test -t 0 && echo "$err" >&2 # send errors to stderr if on terminal
logger -p local0.critical -t $(hostname -s) "$err" # send to syslog
# You could even add some code here to clean up after script1.sh.
exit 1
fi
fi