分类: LINUX
2005-12-20 21:49:05
shell 下一个 || 和 &&问题
【问题】
如果文件存在,就以0为码退出;如果文件不存在,显示"not exists"以后以100为码退出;
【问题代码】
test -e $1 || ( echo "$1 not exists" && exit 100)
exit 0
【现象】
无论文件是否存在,都从exit 0退出了,exit 100似乎没有得到调用。
如果改成
test -e $1 || echo "$1 not exists" && exit 100
exit 0
则无论文件是否存在,都从exit 100退出了,exit 0得不到执行。
【解决】
使用{}代替()
【分析】
在Bash shell中,()的意义是启动一个sub-shell,其中的( ... && exit 100)指退出这个sub-shell,后面的代码还是要执行的;{}才是真正的“代码块”标记。
有什么不对的地方,请大家指正。
关于()的意义和用法,哪位可以深入地讲讲?
回复
请看:
$a=10
$[ $a -eq 20 ] || echo "hello" #输出hello
hello
$[ $a -eq 10 ] || echo "hello" #没有输出hello
这和C语言中是一样的 增加执行效率 当||运算的前一个表达式已经不成立的时候 ,||后面的语句没有必要执行
所以
test -e $1 || (echo "$1 not exists" && exit 100)
exit 0
当$1存在的时候,后面的()里面的内容没有执行,而执行exit 0
当$1不存在的时候,执行()里面的内容在sub-shell中 , 并且sub-shell返回100给当前shell,
然后还要执行当前shell的最后一条语句exit 0
所以不管$1是否存在都会以0退出
如果改成
test -e $1 || echo "$1 not exists" && exit 100
我们先来看|| &&的优先级
$echo "a" || echo "b" && echo "c"
a
c
这里可以看到先||再&&,
它先运算 a||b , 如果a||b为真那么运行c,否则不运行c,也是为了效率&&符号左边如果已经不成立了 那么直接跳出这个逻辑运算
而这里test -e $1 || echo "$1 not exists" && exit 100
-e $1 || echo "$1 not exists" 这部分的 echo 无论怎么运行返回都是真,所以无论文件是否存在前面的 || 运算都是真 它一定会去执行后面的exit 100
解决
同上 () {}