一 概述
算术运算符指的是可以在程序中实现加、减、乘、除等数学运算的运算符。Shell中常用的数学运算符如下所示。
+:对两个变量做加法。
-:对两个变量做减法。
*:对两个变量做乘法。
/:对两个变量做除法。
**:对两个变量做幂运算。
%:取模运算,第一个变量除以第二个变量求余数。
+=:加等于,在自身基础上加第二个变量。
-=:减等于,在第一个变量的基础上减去第二个变量。
*=:乘等于,在第一个变量的基础上乘以第二个变量。
/=:除等于,在第一个变量的基础上除以第二个变量。
%=:取模赋值,第一个变量对第二个变量取模运算,再赋值给第一个变量。
在使用这些运算符时,需要注意到运算顺序的问题。例如输入下面的命令,输出1+2的结果。echo 1+2
Shell并没有输出结果3,而是输出了1+2。在shell中有三种方法可以更改运算顺序。
— 用expr改变运算顺序。可以用echo `expr 1 + 2`来输出1+2的结果,用expr表示后面的表达式为一个数学运算。需要注意的是,`并不是一个单引号,而是“Tab”键上面的那个符号。
— 用$(())表示数学运算。可以先将运算的结果赋值给变量b,运算命令是b=$((1 + 2))。然后用echo $b来输出b的值。将会输出结果3。
— 用$[]表示数学运算。将一个数学运算写到$[]符号的中括号中,中括号中的内容将先进行数学运算。例如命令echo $[1+2],将输出结果3。
二 使用探索
表达式替换$[ ] 和 $(())
表达式操作命令expr
(1)有关空格
$[]表示形式告诉 shell 对方括号中的表达式求值,也可以使用$(())
echo $[ 2 + 3 ]在方括号中的空格并不影响对表达式的理解即其可以写为$[2+3],$[ 2+3],$[2 + 3],$[5**3]等形式
但expr使用时请注意空格:
如echo `expr 8 / 2` 只有这种情况加空格是对的,在紧挨着符号``的两边加空格也是允许的
返回值:当表达式退出不是空null也不是0,返回值为0
当表达式是空null或0时,返回值为1
当表达式在语法上(或语句构成上)无效时,返回值为2
当表达式有发生错误时,返回值为3
(2)有关连续四则运算
$[ 2 +4*2 /3 ],$((2*3-5+3/2 )),`expr 8 / 2 + 3`都是对的
(3)加入改变优先顺序的括号
$[ ((2 +4)*2 -10) /5 ]可以像写普通算式一样使用小括号
$((2*(5-(5+3)/2 )))也可以像写普通算式一样使用小括号
,但expr是绝对不能在里面加上括号的,例echo ` expr ( 8 / 2 ) `是错误的,应这样使用如`expr 8 / \( 2 + 2 \)`,即在()前加反斜杠进行转义
(4)两种格式功能一样,所有的 shell 的求值都是用整数完成
即不接受小数,如$[2.5*2]或$((3.3-2))或expr 2.5 * 3的形式,否则会给出语法错误
(5)$[ ] 可以接受不同基数的数字
$[ 0xa+ 071-3]使用了十六进制的0xa和八进制的071,而默认的为十进制数3
而expr不接受其它进制的数,虽然以下命令`expr 071 + 3`可以语法通过并计算,但值却为74,即将原意输入为八进制的71,理解为十进制数,而十六进制数直接进行语法错误的提示
(6)以上都是常量进行算术四则运算时的操作,对于变量的四则运算操作则如下:
foo=0;
foo=`expr $foo + 1`;echo "foo is $foo";
fly=$[3+5];
fly+=$[ $foo + 1];
fly2=$(($foo+1));
echo "foo is $foo,fly is $fly,fly2 if $fly2";
可见,$[],$(())和expr都可以对变量进行操作。
注意1:无论是左边的变量还是右边的表达式与等号之间不能有空格,即使是+=类的组合赋值符号与变量和表达式之间也不能有空格。
注意2:括在(( ))中的变量不需要使用美元符$,即fly2=$((foo+1));也是对的。
(7)对字符操作
expr与$[]和$(())最大的不同就是能接受字符,可以对字符进行处理如以下的三条命令
expr aaa : 'a\+'
expr abc : 'a\(.\)c'
expr index abcdef cz
(8)对各别运算符号的特别处理
expr在使用乘法时,应使用如expr 8 \* 8的方式才是对的,即在shell编程和shell的终端输入时都需要反斜杠对*号进行转义,才能正常使用乘符号。
还有幂运算符**,即使这样的形式`expr 8 \*\* 2`也不能正常使用,我还没找到在expr中正确的幂运算符的办法,有哪位大侠知道,请不吝赐教!
(9)有关浮点数的计算
bash只具备基本的数学计算能力,不支持浮点数的计算,expr和let等都只支持整型计算。若需要浮点数的计算,可借助如bc,awk或perl等工具。
使用bc,其格式为variable=$(echo "OPTIONS; OPERATIONS" | bc) ,以下有几个例子:
1。echo "3.22*4.32" | bc
2. echo "size=4;2.34*6.77" | bc
3. xx=3.45;yy=$(echo "$xx"| bc);echo "the result is $yy";
bc,也可以有-l参数,表明调用数学库,如术。4;汉。6;echo "$s+0.5^$i"|bc -l
做了归纳总结这后,发现原来[]即是test,而(())操作即是let操作,下面有对二者的总结性描述:
单方括号的test命令通常用内置的test命令来测试表达式值,test命令也被链接到方括号上。这样,既可以使用单独的test命令,也可以通过把表达式用单方括号括起来,来测试表达式的值。在用test命令或方括号测试表达式时,表达式中的shell元字符不会被扩展。由于要对变量进行单词分离,因此包含空白符的字符串必须用引号括起来。
双方括号的test命令2.x版bash中,用双方括号[[ ]](内置的test复合命令)来测试表达式的值,其中,对变量不进行单词分离,但可以通过元字符扩展进行模式匹配。包含空白符的字符串必须用引号括起来。如果一个字符串(不管含不含空白符)仅仅是在表达式中作为一个普通字符串,而不是一个模式的一部分,则它也必须用引号括起来。逻辑操作符& &(与)和| | (或)代替了与test命令一起使用的-a和-o选项
let命令和带双圆括号的算术运算 虽然test命令可以计算算术表达式的值,但读者可能更愿意使用let命令,因为let命令带有丰富的类C操作符(bash 2.x)。let命令可以将表达式包含在一组圆括号中来表达不同的含义。
不管使用的是test命令、复合命令还是let命令,表达式的结果都会被测试。返回零表示成功,而返回非零状态表示失败
这里提到了复合test运算(双方括号),例子如下:
varh="hello";if [ $varh == "hello" ];then echo "hi";else echo "bye";fi;
varh="hello";if [[ $varh == "hello" ]];then echo "hi";else echo "bye";fi;
当这种情况时,双括号与单括号同义,可以互换使用。
但下面情形则不可以互换:
varh="hello";if [[ $varh == [Hh]ell? ]];then echo "hi";else echo "bye";fi;
双方括号可以进行模式匹配,它可以进行元字符的括展,也就是说可以使用元字符如*?[]等等进行模式匹配。
参考文献:
Shell编程笔记(1)-变量和运算符
完全手册Linux系统下C程序开发详解
test与let。http://blog.chinaunix.net/u2/81377/showart_1287413.html
阅读(2345) | 评论(0) | 转发(0) |