shell十三问之十

  rel="File-List" href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C18%5Cclip_filelist.xml">

10) && || 差在哪?

 



好不容易,进入两位数的章节了 ... 一路走来,很辛苦吧?也很快乐吧?   ^_^

在解答本章题目之前,先让我们了解一个概念: return value
我们在 shell 下跑的每一个 command function ,在结束的时候都会传回父行程一个值,称为 return value
shell command line 中可用 $? 这个变量得到最 " " 的一个 return value ,也就是刚结束的那个行程传回的值。
Return Value(RV)
的取值为 0-255 之间,由程序 ( script) 的作者自行定议:
*
若在 script 里,用 exit RV 来指定其值,若没指定,在结束时以最后一道命令之 RV 为值。
*
若在 function 里,则用 return RV 来代替 exit RV 即可。

Return Value
的作用,是用来判断行程的退出状态 (exit status) ,只有两种:
* 0
的话为 " "( true )
*
  0 的话为 " "( false )

举个例子来说明好了:
假设当前目录内有一份 my.file 的文件,而 no.file 是不存在的:


CODE:[Copy to clipboard]$ touch my.file
$ ls my.file
$ echo $?        # first echo
0
$ ls no.file
ls: no.file: No such file or directory
$ echo $?        # second echo
1
$ echo $?        # third echo
0
上例的第一个 echo 是关于 ls my.file RV ,可得到 0 的值,因此为 true
第二个 echo 是关于 ls no.file RV ,则得到非 0   的值,因此为 false
第三个 echo 是关于第二个 echo $? RV ,为 0 的值,因此也为 true

请记住:每一个 command 在结束时都会送回 return value 的﹗不管你跑甚么样的命令 ...
然而,有一个命令却是 " 专门 " 用来测试某一条件而送出 return value 以供 true false 的判断,
它就是 test 命令了﹗
若你用的是 bash ,请在 command line 下打 man test man bash 来了解这个 test 的用法。
这是你可用作参考的最精确的文件了,要是听别人说的,仅作参考就好 ...
下面我只简单作一些辅助说明,其余的一律以 man 为准:

首先, test 的表示式我们称为 expression ,其命令格式有两种:


CODE:[Copy to clipboard]test expression
or:
[ expression ]
(
请务必注意 [ ] 之间的空格键﹗ )
用哪一种格式没所谓,都是一样的效果。 ( 我个人比较喜欢后者 ...)

其次, bash test 目前支持的测试对像只有三种:
* string
:字符串,也就是纯文字。
* integer
:整数 ( 0 或正整数,不含负数或小数点 )
* file
:文件。
请初学者一定要搞清楚这三者的差异,因为 test 所用的 expression 是不一样的。
A=123 这个变量为例:
* [ "$A" = 123 ]
:是字符串的测试,以测试 $A 是否为 1 2 3 这三个连续的 " 文字 "
* [ "$A" -eq 123 ]
:是整数的测试,以测试 $A 是否等于 " 一百二十三 "
* [ -e "$A" ]
:是关于文件的测试,以测试 123 这份 " 文件 " 是否存在。

第三,当 expression 测试为 " " 时, test 就送回 0 (true) return value ,否则送出非 0 (false)
若在 expression 之前加上一个 " ! "( 感叹号 ) ,则是当 expression " 假时 " 才送出 0 ,否则送出非 0
同时, test 也允许多重的覆合测试:
* expression1 -a expression2
:当两个 exrepssion 都为 true ,才送出 0 ,否则送出非 0
* expression1 -o expression2
:只需其中一个 exrepssion true ,就送出 0 ,只有两者都为 false 才送出非 0
例如:


CODE:[Copy to clipboard][ -d "$file" -a -x "$file" ]
是表示当 $file 是一个目录、且同时具有 x 权限时, test 才会为 true

第四,在 command line 中使用 test 时,请别忘记命令行的 " 重组 " 特性,
也就是在碰到 meta 时会先处理 meta 再重新组建命令行。 ( 这个特性我在第二及第四章都曾反复强调过 )
比方说,若 test 碰到变量或命令替换时,若不能满足 expression 格式时,将会得到语法错误的结果。
举例来说好了:
关于 [ string1 = string2 ] 这个 test 格式,
= 号两边必须要有字符串,其中包括空 (null) 字符串 ( 可用 soft quote   hard quote 取得 )
假如 $A 目前没有定义,或被定议为空字符串的话,那如下的写法将会失败:


CODE:[Copy to clipboard]$ unset A
$ [ $A = abc ]
[: =: unary operator expected
这是因为命令行碰到   $ 这个 meta 时,会替换 $A 的值,然后再重组命令行,那就变成了:
[ = abc ]
如此一来 = 号左边就没有字符串存在了,因此造成 test 的语法错误﹗
但是,下面这个写法则是成立的:


CODE:[Copy to clipboard]$ [ "$A" = abc ]
$ echo $?
1
这是因为在命令行重组后的结果为:
[ "" = abc ]
由于 = 左边我们用 soft quote 得到一个空字符串,而让 test 语法得以通过 ...

读者诸君请务必留意这些细节哦,因为稍一不慎,将会导至 test 的结果变了个样﹗
若您对 test 还不是很有经验的话,那在使用 test 时不妨先采用如下这一个 " 法则 "
*
假如在 test 中碰到变量替换,用 soft quote 是最保险的﹗
若你对 quoting 不熟的话,请重新温习第四章的内容吧 ...  ^_^

okay
,关于更多的 test 用法,老话一句:请看 man page 吧﹗   ^_^

虽然洋洋洒洒讲了一大堆,或许你还在嘀咕 .... ... 那个 return value 有啥用啊?﹗
问得好﹗
告诉你: return value 的作用可大了﹗若你想让你的 shell " 聪明 " 的话,就全靠它了:
*
有了 return value ,我们可以让 shell 跟据不同的状态做不同的时情 ...

这时候,才让我来揭晓本章的答案吧 ~~~  ^_^
&&
|| 都是用来 " 组建 " 多个 command line 用的:
* command1 && command2
:其意思是 command2 只有在 RV 0 (true) 的条件下执行。
* command1 || command2
:其意思是 command2 只有在 RV 为非 0 (false) 的条件下执行。
来,以例子来说好了:


CODE:[Copy to clipboard]$ A=123
$ [ -n "$A" ] && echo "yes! it's ture."
yes! it's ture.
$ unset A
$ [ -n "$A" ] && echo "yes! it's ture."
$ [ -n "$A" ] || echo "no, it's NOT ture."
no, it's NOT ture.
(
注: [ -n string ] 是测试 string 长度大于 0 则为 true )
上例的第一个 && 命令行之所以会执行其右边的 echo 命令,是因为上一个 test 送回了 0 RV 值﹔
但第二次就不会执行,因为为 test 送回非 0 的结果 ...
同理, || 右边的 echo 会被执行,却正是因为左边的 test 送回非 0 所引起的。

事实上,我们在同一命令行中,可用多个 && || 来组建呢:


CODE:[Copy to clipboard]$ A=123
$ [ -n "$A" ] && echo "yes! it's ture." || echo "no, it's NOT ture."
yes! it's ture.
$ unset A
$ [ -n "$A" ] && echo "yes! it's ture." || echo "no, it's NOT ture."
no, it's NOT ture.
怎样,从这一刻开始,你是否觉得我们的 shell " 很聪明 " 的呢?   ^_^

好了,最后,布置一道习题给大家做做看、、、
下面的判断是:当 $A 被赋与值时,再看是否小于 100 ,否则送出 too big!


CODE:[Copy to clipboard]$ A=123
$ [ -n "$A" ] && [ "$A" -lt 100 ] || echo 'too big!'
too big!
若我将 A 取消,照理说,应该不会送文字才对啊 ( 因为第一个条件就不成立了 )...


CODE:[Copy to clipboard]$ unset A
$ [ -n "$A" ] && [ "$A" -lt 100 ] || echo 'too big!'
too big!
为何上面的结果也可得到呢?
又,如何解决之呢?
(
提示:修改方法很多,其中一种方法可利用第七章介绍过的 command group ...)

快﹗告我我答案﹗其余免谈 ....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值