一、shell-变量的数值运算符-计算双括号(())的使用
- 变量的数值计算
变量的数值计算常见的如下几个命令:
(())、let、expr、bc、$[]
- (())用法:(此法很常用,且效率高)
执行简单的整数运算,只需将特定的算术表达式用"$(("和"))"
扩起。
shell的算术运算符合都置于"$(("......."))"
的语法中。这一语法如同双引号功能,除了内嵌双引号无需转义。
2. 下面举例
范例1:shell的算术运算实例如下:
[root@1-241 scripts]# ((a=1+2**3-4%3))
[root@1-241 scripts]# echo $a
8
[root@1-241 scripts]# b=$((1+2**3-4%3))
[root@1-241 scripts]# echo $b
8
[root@1-241 scripts]# echo $((1+2**3-4%3))
8
提示:上面是三种不同的变量计算定义和使用的方式。
[root@1-241 scripts]# echo $((a+=1)) #赋值运算符(相当于a=a+1)
9
[root@1-241 scripts]# echo $((a++))
9
[root@1-241 scripts]# echo $a
9
[root@1-241 scripts]# echo $((3>2)) #比较大小,3大于2,得出结果为1,在(())里比较大小,1为真,0为假
1
[root@1-241 scripts]# echo $((3<2)) #比较大小,3小于2,得出结果为0,在(())里比较大小,1为真,0为假
0
[root@1-241 scripts]# a=$((100*(100+1)/2))
[root@1-241 scripts]# echo $a
5050
提示:
1) **为幂运算:%为去模运算(就是除法当中取余数),加减乘除就不细说了
2) 上面涉及到的参数变量必须为整数(整型)。不能是小数(浮点数)或者字符串。后面的bc命令可以进行浮点数运算,但一般较少用到,下文会讲解。提醒下,你可以直接在shell脚本中使用上述命令进行计算。
3) echo $((a++))
和echo $((a--))
表示先输出a自身的值,然后在进行++ --的运算,echo $((++a))
和 echo $((--a))
表示先先进行++ --的运算,在输出a自身的值。
记忆方法:变量在前,先输出变量值,变量在后,就是先运算后输出变量的值。
范例2:–,++在变量前后的举例理解:
[root@1-241 scripts]# a=10
[root@1-241 scripts]# echo $a
10
[root@1-241 scripts]# echo $((a++)) #先输出a的值,因为a为10,所以输出10
10
[root@1-241 scripts]# echo $a #上面输出a的值后,a自赠1,因此a为11
11
[root@1-241 scripts]# echo $((a--))
11
[root@1-241 scripts]# echo $a
10
[root@1-241 scripts]# echo $((++a))
11
[root@1-241 scripts]# echo $((--a))
10
[root@1-241 scripts]# echo $a
10
范例3:定义变量计算的例子:
[root@1-241 scripts]# myvar=99
[root@1-241 scripts]# echo $(($myvar + 1 ))
100
[root@1-241 scripts]# echo $(( $myvar + 1 )) #( ( ) ) 两边有几个空格不敏感,也可以没有。
100
[root@1-241 scripts]# myvar=$(( $myvar + 1 )) #还可以赋值给变量然后输出变量。
[root@1-241 scripts]# echo $myvar
100
范例4:各种(())的计算命令行执行例子:
[root@1-241 scripts]# echo $(( 100 / 5 )) #除法,取商数
20
[root@1-241 scripts]# echo $(( 100 + 5 ))
105
[root@1-241 scripts]# echo $(( 100 * 5 ))
500
[root@1-241 scripts]# echo $(( 100 - 5 ))
95
[root@1-241 scripts]# echo $(( 100 ** 5 )) #次方
10000000000
[root@1-241 scripts]# echo $(( 100 % 5 )) #取模,余数
0
范例5:各种(())运算的shell脚本例子
[root@1-241 scripts]# cat test_shuangkuohao.sh
#!/bin/bash
a=6
b=2
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a %$b ))"
执行结果如下:
[root@1-241 scripts]# sh test_shuangkuohao.sh
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0
范例6:把a、b两个变量通过命令行传参的方式实现上面的混合运算脚本的功能
[root@1-241 scripts]# cat test_shuangkuohao.sh
#!/bin/bash
a=$1
b=$2
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a %$b ))"
执行结果:
[root@1-241 scripts]# sh test_shuangkuohao.sh 6 2
a-b=4
a+b=8
a*b=12
a/b=3
a**b=36
a%b=0
二 、shell-变量的数值运算let内置命令
- let命令的用法
格式:
let 赋值表达式
【注】let赋值表达式功能等同于:((赋值表达式))
范例1:给自变量i加8
[root@1-241 scripts]# i=2
[root@1-241 scripts]# let i=i+8
[root@1-241 scripts]# echo $i
10
[root@1-241 scripts]# i=i+8 #去掉let定义
[root@1-241 scripts]# echo $i
i+8 输出的结果
提示:let i=i+8等同于((i=i+8)),但后者效率更高
三、shell-变量的数值运算与特殊应用expr
- expr(evaluate expressions)命令的用法:
expr命令一般用于整数值,当也可用于字符串,用来求表达式变量的值,同时expr也是一个手工命令行计算器。
语法:expr expression
[yanwei@yanwei-04 logs]$ expr 2 + 2
4
[yanwei@yanwei-04 logs]$ expr 2 - 2
0
[root@1-241 ~]# expr 2 * 2
expr: 语法错误
[root@1-241 ~]# expr 2 \* 2
4
[root@1-241 ~]# expr 2 + 2
4
[root@1-241 ~]# expr 2+2
2+2
[root@1-241 ~]# expr 2 / 2
1
[root@1-241 ~]# expr 2 \*\* 2
expr: 语法错误
[root@1-241 ~]# expr 2 % 2
0
提示:
1) 注意运算符左右都有空格
2) 使用乘号时,必须用反斜线屏蔽其特定含义。因为shell可能会误解星号的含义。
- 增量计数
expr在循环中可用于增量计算。首先,循环初始化为0,然后循环值加1,反引号的用法为命令替代,最基本的一种是从expr命令接收输出并将之放入循环变量。
例:给自变量i加1
[root@1-241 ~]# i=0
[root@1-241 ~]# i=`expr $i + 1`
[root@1-241 ~]# echo $i
1
expr$[$a+$b]表达式形式,其中$a $b可以为整数值
[root@1-241 ~]# expr $[2+3]
5
[root@1-241 ~]# expr $[2*3]
6
[root@1-241 ~]# expr $[2**3]
8
[root@1-241 ~]# expr $[2/3]
0
[root@1-241 ~]# expr $[2%3]
2
[root@1-241 ~]# a=5
[root@1-241 ~]# b=6
[root@1-241 ~]# expr $[$a+$b]
11
expr 将其后的串解释为表达式并计算其值,运算符前后需有空格
其他特殊用法:
expr 用法ssh-copy-id脚本
if expr "$1":".*\.pub" ; then
#expr id_dsa.pub : '.*\.pub',匹配*.pub格式的文件如果是则为真。例:
#[oldboy@oldboy .ssh]$ expr "id_dsa.pub" : ".*\.pub"
#10 这里是匹配后字符数
#man expr
#string :regexp
anchored pattern match of regexp in string
[root@1-241 ~]# expr "test.pub" : ".*\.pub" && echo 1 ||echo 0
8
1
[root@1-241 ~]# expr "test.x" : ".*\.pub" && echo 1 ||echo 0
0
0
通过expr判断变量是否为整数
[root@1-241 scripts]# cat judge_int.sh
read -p "pls input:"a
expr $a + 0 &>/dev/null
[ $? -eq 0 ] && echo int||echo chars
执行完
[root@1-241 scripts]# sh judge_int.sh
pls input:a
chars
加强版:持续等待输入连续判断,整数就退出,错误继续判断输入
[root@1-241 scripts]# cat judge_int.sh
while true
do
read -p "pls input:" a
expr $a + 0 &>/dev/null
if [ $? -eq 0 ]
then
echo int
exit 1
else
echo chars
fi
done<br>
执行结果:
[root@1-241 scripts]# sh judge_int.sh
pls input:a
chars
pls input:r
chars
pls input:12
int
通过expr计算字符串的长度
[root@1-241 scripts]# chars=`seq -s" " 100`
[root@1-241 scripts]# echo ${#chars}
291
[root@1-241 scripts]# echo $(expr length "$chars")
291
四、shell-变量的数值运算-bc-typeset-中括号等方法介绍
- bc命令的用法:
bc是unix下的计算器,它也可以用在命令行下面:
例:给自变量i加1
i=2
i=echo $i + 1|bc
--------效率低
因为bc支持科学计算,所以这种方法功能非常强大
echo $i + 1|bc
[root@1-241 scripts]# echo 3.5+5|bc
8.5
[root@1-241 scripts]# echo 3.5+8|bc
11.5
[root@1-241 scripts]# echo 3.5+8.9|bc
12.4
[root@1-241 scripts]# echo "scale=1;5.23 * 3.13"|bc
16.36
[root@1-241 scripts]# echo "obase=2;8"|bc #把十进制转换成二进制
1000
[root@1-241 scripts]# echo "obase=2;4"|bc
100
[root@1-241 scripts]# echo "obase=2;1"|bc
1
[root@1-241 scripts]# echo "obase=2;2"|bc
10
[root@1-241 scripts]# echo "obase=16;20"|bc #把十进制转换成十六进制
14
[root@1-241 scripts]# seq -s "+" 10|bc
55
特点: bc的特点是支持小数运算
- typeset命令的用法:
使用整数变量直接进行计算
例如:
[root@1-241 scripts]# typeset -i A=1 B=3
[root@1-241 scripts]# A=A+B
[root@1-241 scripts]# echo $A
4
- $[ ]的用法:
实践操作演示:
[root@1-241 scripts]# echo $[3+2]
5
[root@1-241 scripts]# echo $[3-2]
1
[root@1-241 scripts]# echo $[3*2]
6
[root@1-241 scripts]# echo $[3/2]
1
[root@1-241 scripts]# echo $[3**2]
9
[root@1-241 scripts]# echo $[3%2]<br>
实际解决问题例子:打印数学杨辉三角
#!/bin/bash
if (test -z $1) ;then
read -p "Input Max Lines:" MAX
else
MAX=$1
fi
i=1
while [ $i -le $MAX ] #i行控制
do
j=1
while [ $j -le $i ] #j列控制
do
f=$[i-1] #f=i-1 这是另一种计算写法。
g=$[j-1] #g=j-1 这是另一种计算写法。
if [ $j -eq $i ] || [ $j -eq 1 ] ; then
declare SUM_${i}_$j=1 #声明变量 头尾都是1
else
declare A=$[SUM_${f}_$j] #取上一行的j列变量
declare B=$[SUM_${f}_$g] #取上一行的j-1列变量
declare SUM_${i}_$j=`expr $A + $B` #声明并计算当前变量的值
fi
echo -en $[SUM_${i}_$j]" " #输出当前变量
let j++
done
echo #换行
let i++
done
五、shell-变量输入内置read命令详解
- shell变量的输入
shell变量除了可以直接赋值或脚本传参外,还可以使用read命令从标准输入得。
【语法格式】
read [参数] [变量名]
【常用参数】
-p:指定读取值时的提示符;
-t: 指定读取值时等待的时间(秒)。
-n:字符数:read命令只接受指定的字符数,就会执行
-s:隐藏输入的数据,适用于机密信息的输入 - 举例
范例1:read的基本读入
[root@1-241 scripts]# read -p "please input two nomber:" a1 a2 //读入键盘输入的值到变量 a1 和 a2
please input two nomber:12 13 //键盘输入 12 13
[root@1-241 scripts]# echo $a1 $a2 //查看变量a1 a2的值 显示如下
12 13
提示:上面read -p 的功能可以用echo和read实现。
echo -n "please input two number:"
read a1 a2
以上两句和下面的命令相当(-t 排除在外)
read -t 5 -p "please input two nomber:" a1 a2 #5 秒超时退出
范例2:实践考试题
把加减乘除计算的脚本改成通过read方式读入整数变量:
[root@1-241 scripts]# cat test_shuangkuohao.sh
#!/bin/bash
a=$1
b=$2
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a %$b ))"
范例2:的参考答案
[root@1-241 scripts]# cat test_read.sh
#!/bin/bash
read -p "please input two number:" a b //在脚本加入此句即可
echo "a-b=$(( $a - $b ))"
echo "a+b=$(( $a + $b ))"
echo "a*b=$(( $a * $b ))"
echo "a/b=$(( $a / $b ))"
echo "a**b=$(( $a ** $b ))"
echo "a%b=$(( $a %$b ))"
六、shell-添加条件测试的多种方法语法介绍与简单实战
1. 条件测试
- 测试语句
1) 条件测试语法
在bash的各种流程控制结构中通常要进行各种测试,然后根据测试结果执行不同的操作,有时也会通过与if等条件语句相结合,使我们可以方便的完成判断。
2) 【语法说明】
格式1:test<测试表达式>
格式2:[<测试表达式>]
格式3:[[<测试表达式>]]
说明:
格式1和格式2是等价的。
格式3为扩展的test命令,有网友推荐用推荐3,老男孩习惯使用格式2.
提示:
在[[]]中可以使用通配符进行模式匹配。&&、||、>、<等操作符可以应用于[[]]中,但不能应用于[]中。
对整数进行关系运算,也可以使用shell的算术运算符(())。
2.文件测试操作符
3.语法例子
格式1:test<测试表达式>
范例1:test测试文件
[root@1-241 scripts]# test -f file && echo true ||echo false
false
[root@1-241 scripts]# touch file
[root@1-241 scripts]# test -f file && echo true ||echo false
true
范例2:test命令非(!)的写法
[root@1-241 scripts]# test ! -f file && echo true ||echo false
true
[root@1-241 scripts]# touch file
[root@1-241 scripts]# test ! -f file && echo true ||echo false
false
格式2:[<测试表达式>]
范例:[ ]
[root@1-241 scripts]# [ -f file ] && echo true ||echo false
false
[root@1-241 scripts]# touch file
[root@1-241 scripts]# [ -f file ] && echo true ||echo false
true
[root@1-241 scripts]# [ -f file ] && cat file
[root@1-241 scripts]# rm -rf file
[root@1-241 scripts]# [ -f file ] && cat file
[root@1-241 scripts]# cat file
cat: file: 没有那个文件或目录
格式3:[[<测试表达式>]]
范例:[ [ ] ]
[root@1-241 scripts]# [[ -f file ]] && echo true || echo false
false
[root@1-241 scripts]# [[ ! -f file ]] && echo true || echo false
true
[root@1-241 scripts]# [[ -f file && -f folder ]] && echo true || echo false
false
[root@1-241 scripts]# [ -f file && -f folder ] && echo true || echo false
-bash: [: missing `]'
false
[root@1-241 scripts]# [ -f file -a -f folder ] && echo true || echo false
false
[root@1-241 scripts]# touch file folder
[root@1-241 scripts]# [ -f file -a -f folder ] && echo true || echo false
true
[root@1-241 scripts]#
[root@1-241 scripts]# rm -rf file
[root@1-241 scripts]# [ -f file -a -f folder ] && echo true || echo false
false
七、shell-字符串及整数操作符讲解与多实践
- 字符串测试操作符
字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为零,字符串是否为null(注:bash区分零长度字符串和空字符串)等。
“=”
比较两个字符串是否相同,与==等价,如if[ "$a" = "$b" ]
,其中$a
这样的变量最好用""括起来,因为如果中间有空格,*等符号就可能出错了,当然更好的方法就是[ "${a}" = "${b}" ]
。"!="
比较两个字符串是否相同,不同则为“是”。
在书写测试表达式时,可以使用表1.3.1中的字符串测试操作符。
表1.3.1中 字符串测试操作符
特别注意:以上表格中的字符串测试操作符号务必要用" "
引起来。
字符串测试操作符提示:
1. -n 比较字符串长度是否不为零,如果不为零则为真,如: [ -n "$myvar" ]
2. -z 比较字符串长度是否等于零,如果等于零则为为真,如:[ -z "$myvar" ]
2. 整数二元比较操作符
在书写测试表达式时,可以使用表1.3.6中的整数二元比较操作符
表1.3.6中整数二元比较操作符、
提示:
“<”
符号意思是小于,if [[ "$a" < "$b" ]],if[ "$a" \< "$b" ]
。在单[ ]中需要转义,因为shell也用“<”
和“>”
重定向“>”
符号意思是小于,if [[ "$a" > "$b" ]],if[ "$a" \> "$b" ]
。在单[ ]中需要转义,因为shell也用“<”
和“>”
重定向“=”
符号意思是小于,if [[ "$a" = "$b" ]],if[ "$a" = "$b" ]
。在单[ ] 中不需要转义
提示:
经过实践,"="
和"!="
在[ ]中使用不需要转义,包含">"
和"<"
的符号在[ ]中使用需要转义,对于数字不转义的结果未必会报错,但是结果可能不会对。
范例1:二元数字比较
[root@test-1 ~]# [ 2 > 1 ] && echo 1 ||echo 0
1
[root@test-1 ~]# [ 2 < 1 ] && echo 1 ||echo 0
1 #这里的结果逻辑不对,条件不成立,应该返回 0
[root@test-1 ~]# [ 2 \< 1 ] && echo 1 ||echo 0
0 #转义后是正确的。
[root@test-1 ~]# [ 2 -gt 1 ] && echo 1 ||echo 0
1
[root@test-1 ~]# [ 2 -lt 1 ] && echo 1 ||echo 0
0
[root@test-1 ~]# [ 2 > 1 ] && echo 1 ||echo 0
1
[root@test-1 ~]# [[ 2 > 1 ]] && echo 1 ||echo 0
1
[root@test-1 ~]# [[ 2 < 1 ]] && echo 1 ||echo 0
0
[root@test-1 ~]# [ 2 = 1 ] && echo 1 ||echo 0
0
[root@test-1 ~]# [ 1 = 1 ] && echo 1 ||echo 0
1
[root@test-1 ~]# [ 2 = 1 ] && echo 1 ||echo 0
0
[root@test-1 ~]# [ 2 = 2 ] && echo 1 ||echo 0
1
[root@test-1 ~]# [ 2 != 2 ] && echo 1 ||echo 0
0
提示:经过实践,“=”和“!=”在[ ]中使用不需要转义也可以。
[root@test-1 ~]# [[ 2 -lt 1 ]] && echo 1 ||echo 0
0
[root@test-1 ~]# [[ 2 -gt 1 ]] && echo 1 ||echo 0
1
范例2:二元字符比较
[root@test-1 ~]# [ "a" > "bc" ] && echo 1 ||echo 0
1
[root@test-1 ~]# [ "a" < "bc" ] && echo 1 ||echo 0
1 #上面两个条件不一样,但结果一样,虽然没报语法错误,但显然不对。
[root@test-1 ~]# [ "a" \> "bc" ] && echo 1 ||echo 0
0
[root@test-1 ~]# [ "a" \< "bc" ] && echo 1 ||echo 0
1
#加上对比较的转义后,逻辑上显示正确了。
八、shell-逻辑操作符讲解与文件条件测试多范例
- 逻辑操作符
在书写测试表达式时,可以使用表1.1中的逻辑操作符实现复杂的条件测试
表1.1逻辑连接符
提醒:
1. “-a"和”-o"逻辑操作符号用于[ ]中使用
2. “&&” 和 “||” 逻辑操作符号用于[[ ]]中使用。
3. 注意括号两端,必须要有空格。
- 逻辑操作符运算规则
结论:-a &&的运算规则:只有两端都是1才为真
真 1 假0
---------------------
and 1*0=0 假
and 1*1=1 真
and 0*0=0 假
两端都是1才为真
结论:-o,|| 两端都是0才为假,任何一端不为0都是真
---------------------
or 1+0=1 真
or 1+1=2 真
or 0+1=1 真
or 0+0=0 假
两端都是0才为假,不为0就是真。
- 条件测试举例
下面举一些条件测试的例子。为了清晰的显示测试结果,我们在屏幕上输出1(表示真)或0(表示假)表示测试结果。
提示:这和前面的状态变量"$?"
返回0为真不一样哟
[root@test-1 scripts]# [ -f "$file1" ] && echo 1 || echo 0 #这是条件表达式的用法
0
[root@test-1 scripts]# if [ -f "$file1" ];then echo 1;else echo 0;fi #这是后面要讲的if条件句的语法。
0
提示:
1. 以上两条语句的功能是等同的。
2. 变量$file加了双引号,这是编程的好习惯,可以防止很多意外的错误发生。