标签:shell
严格来说,shell中没有表达式的概念。Shell本身其实只是一堆命令的集合,当然也不是胡乱的堆在一起,而是有一定的组织。只是这个组织不那么严谨,所以本文不是要真的总结所谓的表达式,而是把shell中一些犄角旮旯的东西拼凑在一起,实在不知道它们属于那个分类。。
m@meng:~/scripts$ m=`date`
m@meng:~/scripts$ echo $m
2015年 06月 25日 星期四 10:40:24 CST
m@meng:~/scripts$ n=$(date)
m@meng:~/scripts$ echo $n
2015年 06月 25日 星期四 10:40:37 CST
也就是说,`command`和$(command)的效果是一样的。
m@meng:~/scripts$ r=3+4
m@meng:~/scripts$ echo $r
3+4
m@meng:~/scripts$ echo $(($r))
7
m@meng:~/scripts$ echo $(($r+3))
10
不过,$(()) 中只能用+-*/和()运算符,并且只能做整数运算。
m@meng:~/scripts$ q=5
m@meng:~/scripts$ echo "$q"
5
m@meng:~/scripts$ echo ‘$q‘
$q
所以,在单引号中使用变量一定要小心。
所谓界定符,其实就是将界定符内的字符串视为一个整体,而不会被空格等分隔符打断。
在双引号内,所有的特殊字符将保持其转义含义,如上面的’$’。如果想让双引号中的某个特殊字符恢复其本来面目,即取其字面值,可以在它前面添加转义字符’\’,如下:
m@meng:~/scripts$ echo "\$q"
$q
m@meng:~/scripts$ grep m new
m@meng:~/scripts$ echo $?
1
m@meng:~/scripts$ cat new
的
m@meng:~/scripts$ echo $?
0
m@meng:~/scripts$ m=4
m@meng:~/scripts$ echo $?
0
上例,grep命令在new文件中没有找到字符”m”,所以其出口状态为1;其他都为0,包括赋值语句。
退出状态经常用做if语句的判断条件。
test表达式
虽然可以直接使用命令的出口状态作为if、while等语句的判断条件,但是更常使用的却是test等专门的测试命令。
test命令的语法为:
test 表达式
test主要用来执行三类测试:文件属性、数值比较、字符串比较。如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1。
文件测试
格式为: test options file。主要的options包括:
数字测试
数字测试的比较运算符竟然使用的是文字,对比如下(左侧是C语言使用的传统的运算符,右侧是shell使用的):
== : -eq
!= : -ne
> : -gt
\< : -lt
>= : -ge
\<= : -le
字符串测试
-z str: 若str的长度是0,结果为真(谨记:真 <==> $? == 0)
-n str: 若str的长度不是0,结果为真
s1 = s2 : 两个字符串相等,结果为真
s1 != s2 : 两个字符串不等,结果为真
str : 不加任何选项来测试str,效果同-n
[ ] 表达式
实际上,只有 [ 是命令,而 ] 只是界定符。[ 命令与test命令基本相同,唯一的区别就是格式不同,[ 命令需要将要测试的表达式置于括号中,###且表达式左右两边分别要和[ ]留一个空格###,如[ -z “empty” ]。据说,[ 命令的效率稍微高一些,我没验证过。
还有一点:###[ 命令不支持运算符“>”和“<”###,所以对于字符串比较运算的支持可能差一点,这是唯二的区别。。。。
[[ ]]表达式
扩展了[ ]命令,首先就是支持了运算符“>”和“<”,另外还支持逻辑运算&&,||,!,如下:
m@meng:~/scripts$ [ er > et ]
m@meng:~/scripts$ echo $?
0
m@meng:~/scripts$ [[ er > et ]]
m@meng:~/scripts$ echo $?
1
显然,er > et结果应该为假,所以测试表达式的出口状态是1。但是[]没有效果,而[[ ]]测试正确。
m@meng:~/scripts$ [ er > et || er < et ]
bash: [: 缺少 `]`
er:未找到命令
m@meng:~/scripts$ [[ er > et || er < et ]]
m@meng:~/scripts$ echo $?
0
m@meng:~/scripts$ [[ er > et && er < et ]]
m@meng:~/scripts$ echo $?
1
m@meng:~/scripts$ ((m=4-2))
m@meng:~/scripts$ echo $m
2
m@meng:~/scripts$ m=$((4-2))
m@meng:~/scripts$ echo $m
2
这意味着,((m=4-2))和m=$((4-2))效果是一样的,也就是说在(())内部可以直接完成赋值。
~~~~
m@meng:~/scripts$ echo $((4-2))
2
m@meng:~/scripts$ echo ((4-2))
bash: 未预期的符号 ‘(‘ 附近有语法错误
这说明,(())不负责保存结果,想要结果的话,用’$’来提取。
~~~~
m@meng:~/scripts$ m=3;n=2
m@meng:~/scripts$ echo $((m-n))
1
这说明,在(())内部使用变量时,不需要添加’$’符号。
~~~~
m@meng:~/scripts$ m=3;n=2
m@meng:~/scripts$ echo $((m<n))
0
m@meng:~/scripts$ echo $((m>n))
1
显然,(())还支持比较运算,唯一的问题是,它的出口状态与test等其他命令恰好相反!
~~~~
总结一下这个表达式:
1、只支持整数运算;
2、支持的运算包括:=(赋值)、==(相等)、>= <= < > % + - * / -= += /= *= %=,很丰富了。
逻辑运算
主要有&&、||、-a、-o、!和(),用来计算表达式之间的逻辑运算,支持用括号()来进行组合,逻辑运算符和表达式之间要有空格。
[[]]命令只支持符号,不支持-a和-o选项。
m@meng:~/scripts$ [[ er > et -o er < et ]]
bash: 条件表达式中有语法错误
bash: ‘-o‘ 附近有语法错误
完。
标签:shell
原文地址:http://blog.csdn.net/u012668018/article/details/46638089