Bash作为一个编程语言,有很多奇怪的表达字符,有时候会让人感到很费解,其实,只要我们弄清楚bash面临的问题
就能够理解为啥要这么搞了,举个例子:
1、比较字符串"ab"和"bc"的大小:
#错误,a的ascii码比b小,这里应该为假,但却显示为真 [root@noi ~]# ls alias.set a.out default.pass t t.c t.cpp t.sh wai.bat [root@noi ~]# [ 'ab' > 'bc' ];echo $? 0 [root@noi ~]# ls #这里多了一个bc的文件 alias.set a.out bc default.pass t t.c t.cpp t.sh wai.bat #错误的原因是>号被shell提前执行了,而不是作为参数传递给[,因为>在shell里是有意义的。>作为输出操作符,将test 'ab'的结果输出到文件bc中,这就是为啥多了一个bc的文件。
如果想要正确的执行比较运算,不可能修改test,因为test是一个独立的小程序,也不可能改变>在shell里面的用途,因为输出操作符,我们也常用。
最后,还是转义字符()粉墨登场来救急了,将>前面加上转义字符,这样告诉shell,把它当作一个普通字符,就能够顺利的传递到test命令里面了。
#看,得到正确的答案了吧 [root@noi ~]# [ 'ab' > 'bc' ];echo $? 1
通过以上例子了解到,Shell面临的是一个复杂的环境,每个小程序之间都是独立的,作为粘合剂的它是相当的难做啊!这就是为啥它的语法看起来有点
丑陋了吧,浑身都是坑,能不难看吗?但是,话又说回来了,它确实做到了。虽然哥浑身都是坑,但是,大坑我都填上了,剩下的小坑也可以找到办法
绕过去,你们还是好自为之,多多学习吧,呵呵。
最后,在写一个例子:
假如你要再判断某个目录是否存在,又想当然写成:
[root@noi ~]# [ -f exists.txt && -d exists_folder ]; echo $? -bash: [: missing `]' 2
结果提示漏了右括号,那是因为 &&
被 bash 预先解析了,而不是当成 test 的参数传递。
-
&&
表示如果左边的命令正常执行了,那么继续执行右边的命令,相当于没有 else 部分的 if 语句简化版。 -
而
||
表示如果左边的命令不是正常执行了,那么继续执行右边的命令,相当于没有 then 部分的 if 语句(或者 if not)。
从效果看也可以分别当成逻辑与和逻辑或的。
所以上面那条命令以 [ -f exists.txt
明显是个不完整命令,漏了个 [
。
修正如下:
[root@noi ~]# ls alias.set default.pass exists.txt t.c t.sh a.out exists_folder t t.cpp wai.bat [root@noi ~]# [ -f exists.txt ] && [ -d exists_folder ]; echo $? 0
换成test的写法也可这样写:
[root@noi ~]# test -f exists.txt && test -d exists_folder; echo $? 0