Shell expr命令:对整数进行运算
Shell expr 对于整数计算的用法:
expr 表达式
expr 对表达式
的格式有几点特殊的要求:
- 出现在
表达式
中的运算符、数字、变量和小括号的左右两边至少要有一个空格,否则会报错。 - 有些特殊符号必须用反斜杠
\
进行转义(屏蔽其特殊含义),比如乘号*
和小括号()
,如果不用\
转义,那么 Shell 会把它们误解为正则表达式中的符号(*
对应通配符,()
对应分组)。 - 使用变量时要加
$
前缀。
【实例1】expr 整数计算简单举例:
[c.biancheng.net]$ expr 2 +3 #错误:加号和 3 之前没有空格 expr: 语法错误 [c.biancheng.net]$ expr 2 + 3 #这样才是正确的 5 [c.biancheng.net]$ expr 4 * 5 #错误:乘号没有转义 expr: 语法错误 [c.biancheng.net]$ expr 4 \* 5 #使用 \ 转义后才是正确的 20 [c.biancheng.net]$ expr ( 2 + 3 ) \* 4 #小括号也需要转义 bash: 未预期的符号 `2' 附近有语法错误 [c.biancheng.net]$ expr \( 2 + 3 \) \* 4 #使用 \ 转义后才是正确的 20 [c.biancheng.net]$ n=3 [c.biancheng.net]$ expr n + 2 #使用变量时要加 $ expr: 非整数参数 [c.biancheng.net]$ expr $n + 2 #加上 $ 才是正确的 5 [c.biancheng.net]$ m=7 [c.biancheng.net]$ expr $m \* \( $n + 5 \) 56
以上是直接使用 expr 命令,计算结果会直接输出,如果你希望将计算结果赋值给变量,那么需要将整个表达式用反引号``
(位于 Tab 键的上方)包围起来,请看下面的例子。
【实例2】将 expr 的计算结果赋值给变量:
[c.biancheng.net]$ m=5 [c.biancheng.net]$ n=`expr $m + 10` [c.biancheng.net]$ echo $n 15
Shell $[]:对整数进行数学运算
和 (())、let 命令类似,$[] 也只能进行整数运算,Shell $[] 的用法如下:
$[表达式]
$[] 会对表达式
进行计算,并取得计算结果。如果表达式
中包含了变量,那么你可以加$
,也可以不加。
Shell $[] 举例:
[c.biancheng.net]$ echo $[3*5] #直接输出结算结果 15 [c.biancheng.net]$ echo $[(3+4)*5] #使用() 35 [c.biancheng.net]$ n=6 [c.biancheng.net]$ m=$[n*2] #将计算结果赋值给变量 [c.biancheng.net]$ echo $[m+n] 18 [c.biancheng.net]$ echo $[$m*$n] #在变量前边加$也是可以的 72 [c.biancheng.net]$ echo $[4*(m+n)] 72
需要注意的是,不能单独使用 $[],必须能够接收 $[] 的计算结果。例如,下面的用法是错误的:
[c.biancheng.net]$ $[3+4] bash: 7: 未找到命令... [c.biancheng.net]$ $[m+3] bash: 15: 未找到命令...
Shell (()):对整数进行数学运算
双小括号 (( )) 的语法格式为:
((表达式))
通俗地讲,就是将数学运算表达式放在((
和))
之间。
表达式可以只有一个,也可以有多个,多个表达式之间以逗号,
分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( )) 命令的执行结果。
可以使用$
获取 (( )) 命令的结果,这和使用$
获得变量值是类似的。
运算操作符/运算命令 | 说明 |
---|---|
((a=10+66) ((b=a-15)) ((c=a+b)) |
这种写法可以在计算完成后给变量赋值。以 ((b=a-15)) 为例,即将 a-15 的运算结果赋值给变量 c。 注意,使用变量时不用加 $ 前缀,(( )) 会自动解析变量名。 |
a=$((10+66) b=$((a-15)) c=$((a+b)) |
可以在 (( )) 前面加上$ 符号获取 (( )) 命令的执行结果,也即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。注意,类似 c=((a+b)) 这样的写法是错误的,不加 $ 就不能取得表达式的结果。 |
((a>7 && b==c)) | (( )) 也可以进行逻辑运算,在 if 语句中常会使用逻辑运算。 |
echo $((a+10)) | 需要立即输出表达式的运算结果时,可以在 (( )) 前面加$ 符号。 |
((a=3+5, b=a+10)) | 对多个表达式同时进行计算。 |
在 (( )) 中使用变量无需加上$
前缀,(( )) 会自动解析变量名,这使得代码更加简洁,也符合程序员的书写习惯。
Shell (( )) 实例演示
【实例1】利用 (( )) 进行简单的数值计算。
[c.biancheng.net]$ echo $((1+1)) 2 [c.biancheng.net]$ echo $((6-3)) 3 [c.biancheng.net]$ i=5 [c.biancheng.net]$ ((i=i*2)) #可以简写为 ((i*=2))。 [c.biancheng.net]$ echo $i #使用 echo 输出变量结果时要加 $。 10
【实例2】用 (( )) 进行稍微复杂一些的综合算术运算。
[c.biancheng.net]$ ((a=1+2**3-4%3)) [c.biancheng.net]$ echo $a 8 [c.biancheng.net]$ b=$((1+2**3-4%3)) #运算后将结果赋值给变量,变量放在了括号的外面。 [c.biancheng.net]$ echo $b 8 [c.biancheng.net]$ echo $((1+2**3-4%3)) #也可以直接将表达式的结果输出,注意不要丢掉 $ 符号。 8 [c.biancheng.net]$ a=$((100*(100+1)/2)) #利用公式计算1+2+3+...+100的和。 [c.biancheng.net]$ echo $a 5050 [c.biancheng.net]$ echo $((100*(100+1)/2)) #也可以直接输出表达式的结果。 5050
【实例3】利用 (( )) 进行逻辑运算。
[c.biancheng.net]$ echo $((3<8)) #3<8 的结果是成立的,因此,输出了 1,1 表示真 1 [c.biancheng.net]$ echo $((8<3)) #8<3 的结果是不成立的,因此,输出了 0,0 表示假。 0 [c.biancheng.net]$ echo $((8==8)) #判断是否相等。 1 [c.biancheng.net]$ if ((8>7&&5==5)) > then > echo yes > fi yes
最后是一个简单的 if 语句的格式,它的意思是,如果 8>7 成立,并且 5==5 成立,那么输出 yes。显然,这两个条件都是成立的,所以输出了 yes。
Shell [[]]详解:检测某个条件是否成立
[[ ]]
是 Shell 内置关键字,它和 test命令类似,也用来检测某个条件是否成立。
test 能做到的,[[ ]] 也能做到,而且 [[ ]] 做的更好;test 做不到的,[[ ]] 还能做到。可以认为 [[ ]] 是 test 的升级版,对细节进行了优化,并且扩展了一些功能。
[[ ]] 的用法为:
[[ expression ]]
当 [[ ]] 判断 expression 成立时,退出状态为 0,否则为非 0 值。注意[[ ]]
和expression
之间的空格,这两个空格是必须的,否则会导致语法错误。
[[ ]] 不需要注意某些细枝末节
[[ ]] 是 Shell 内置关键字,不是命令,在使用时没有给函数传递参数的过程,所以 test 命令的某些注意事项在 [[ ]] 中就不存在了,具体包括:
- 不需要把变量名用双引号
""
包围起来,即使变量是空值,也不会出错。 - 不需要、也不能对 >、< 进行转义,转义后会出错。
请看下面的演示代码:
#!/bin/bash
read str1
read str2
if [[ -z $str1 ]] || [[ -z $str2 ]] #不需要对变量名加双引号
then
echo "字符串不能为空"
elif [[ $str1 < $str2 ]] #不需要也不能对 < 进行转义
then
echo "str1 < str2"
else
echo "str1 >= str2"
fi
运行结果:
http://c.biancheng.net/shell/
http://data.biancheng.net/
str1 < str2
[[ ]] 支持逻辑运算符
对多个表达式进行逻辑运算时,可以使用逻辑运算符将多个 test 命令连接起来,例如:
[ -z "$str1" ] || [ -z "$str2" ]
你也可以借助选项把多个表达式写在一个 test 命令中,例如:
[ -z "$str1" -o -z "$str2" ]
但是,这两种写法都有点“别扭”,完美的写法是在一个命令中使用逻辑运算符将多个表达式连接起来。我们的这个愿望在 [[ ]] 中实现了,[[ ]] 支持 &&、|| 和 ! 三种逻辑运算符。
使用 [[ ]] 对上面的语句进行改进:
[[ -z $str1 || -z $str2 ]]
这种写法就比较简洁漂亮了。
注意,[[ ]] 剔除了 test 命令的-o
和-a
选项,你只能使用 || 和 &&。这意味着,你不能写成下面的形式:
[[ -z $str1 -o -z $str2 ]]
当然,使用逻辑运算符将多个 [[ ]] 连接起来依然是可以的,因为这是 Shell 本身提供的功能,跟 [[ ]] 或者 test 没有关系,如下所示:
[[ -z $str1 ]] || [[ -z $str2 ]]
test 或 [] | [[ ]] | ||
---|---|---|---|
[ -z "$str1" ] || [ -z "$str2" ] | √ | [[ -z $str1 ]] || [[ -z $str2 ]] | √ |
[ -z "$str1" -o -z "$str2" ] | √ | [[ -z $str1 -o -z $str2 ]] | × |
[ -z $str1 || -z $str2 ] | × | [[ -z $str1 || -z $str2 ]] | √ |