shell脚本语言的运算
1.条件测试命令
条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程,实现评估布尔声明,以便在条件性环境下进行执行。
* 若真,则状态码变量$?返回0
* 若假,则状态码变量$?返回1
扩展: [ ] 与 [[ ]] 的区别
`区别1:
[ ]是符合POSIX标准的测试语句,兼容性强,几乎可以运行在所有的Shell解释器中
[[ ]]仅可运行在特定的几个Shell解释器中(如Bash)
`区别2:
> < 可以在[[ ]]中使用ASCII码顺序进行排序,而[]不支持
`区别3:
在[ ]中使用-a 和 -o 表示逻辑与和逻辑或,[[ ]]使用&& 和 || 表示,[[ ]]不支持-a
`区别4:
在[ ]中==是字符匹配,在[[ ]]中==是模式匹配
`区别5:
[ ]不支持正则匹配,[[ ]]支持用=~进行正则匹配
`区别6:
[ ]仅在部分Shell中支持用()进行分组,[[ ]]均支持
`区别7:
在[ ]中如果变量没有定义,那么需要用双引号引起来,在[[ ]]中不需要
1.1 条件测试命令及其语法
语法1:test <测试表达式> 说明:test命令和<测试表达式>之间至少有一个空格
##### 4.4.1 条件测试命令及其语法
> 语法1:test <测试表达式> 说明:test命令和<测试表达式>之间至少有一个空格
语法2:[<测试表达式>] 说明:该方法和test命令的用法一样,[]的两边和内容之间至少有一个空格
root@localhost ~]# [ 1 -gt 3 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ 1 -lt 3 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]#
语法3:[[ <测试表达式> ]] 说明:比test和\[\]更新的语法格式。[[]]的边界和内容之间至少有一个空格。[[]]中可以使用通配符等进行模式匹配
[root@localhost ~]# [[ 1 > 3 ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [[ 1 < 3 ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]#
语法4:((<测试表达式>)) 说明:一般用于if语句里,双小括号两端不需要有空格,测试对象只能是整数
[root@localhost ~]# ((1<2))
[root@localhost ~]# echo $?
0
[root@localhost ~]# ((1>2))
[root@localhost ~]# echo $?
1
[root@localhost ~]#
1.2 变量测试
语法规则:-v VAR 变量var是否被定义
示例:判断NAME变量是否被定义
[root@localhost ~]# [[ -v NAME ]]
[root@localhost ~]# echo $?
1
[root@localhost ~]# NAME=1
[root@localhost ~]# [[ -v NAME ]]
[root@localhost ~]#
[root@localhost ~]# echo $?
0
[root@localhost ~]#
语法规则: -R VAR 变量VAR是否被引用
> 示例:判断NAME变量是否被引用
[root@localhost ~]# NAME=10
[root@localhost ~]# test -v NAME
[root@localhost ~]# echo $?
0
[root@localhost ~]# test -R NAME
[root@localhost ~]# echo $?
1
[root@localhost ~]#
1.3 文件测试表达式
| 常用的文件测试操作符 | 说明 |
| -a/-e 文件 | 文件是否存在 |
| -d 文件 | 文件存在且为目录则为真,即测试表达式成立 |
| -f 文件 | 文件存在且为普通文件则为真,即测试表达式成立 |
| -r 文件 | 文件存在且可读为真 |
| -w 文件 | 文件存在且可写为真 |
| -x 文件 | 文件存在且可执行则为真 |
测试文件
[root@localhost ~]# test -a test.txt
[root@localhost ~]# echo $?
1
[root@localhost ~]# test -d shell
[root@localhost ~]# echo $?
0
[root@localhost ~]# touch test.txt
[root@localhost ~]# test -w test.txt &&echo "true"
true
[root@localhost ~]# test -r test.txt &&echo "true"
true
[root@localhost ~]# test -x test.txt &&echo "true"
[root@localhost ~]#
1.4 字符串测试表达式
| 常用字符串测试操作符 | 说明 |
| -z ”字符串“ | 若字符串的长度为0,则为真,z可以理解为zero |
测试字符串
[root@localhost ~]# var_test='mike'
[root@localhost ~]# echo $var_test
mike
[root@localhost ~]# [[ -n var_test ]] && echo "True"
True
1.5 整数测试表达式
| 在[ ] 或 test中使用的比较符号 | 在(( )) 或 [[ ]]中使用的比较符号(不用这个做数字比较) | 说明 |
|
-eq | \== 或 = | 相等 |
| -ne |
!= | 不相等 |
| -gt | > | 大于 |
| -ge | >= | 大于等于 |
| -lt | < | 小于 |
| -le | <= | 小于等于 |
1.6 逻辑操作符
| 在[ ] 中使用的操作符 | 在test, [[ ]] , (( ))中使用的逻辑操作符 | 说明 |
| -a | && | and,与,两边都为真,则结果为真 |
| -o | || | or,或,有真则真,同假则假 |
| ! | ! | not,非,两端相反,则结果相反 |
[root@ansible-salve1 ~]# var_test=1
[root@ansible-salve1 ~]# var_t=2
[root@ansible-salve1 ~]# [ $var_test -lt 0 -a $var_t -gt 0 ]
[root@ansible-salve1 ~]# echo $?
1
[root@ansible-salve1 ~]# [ $var_test -lt 0 -o $var_t -gt 0 ]
[root@ansible-salve1 ~]# echo $?
0
[root@ansible-salve1 ~]#
1.5 关于()与 { }
( )和 { }都可以将多个命令组合再一次,批量执行,{ } 里的内容需要与两侧用空格隔开并在命令结尾加上;
( )会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境
[root@ansible-salve1 ~]# name=mage;(echo $name;name=wang;echo $name);echo $name
mage
wang
mage
[root@ansible-salve1 ~]# (umask 444;umask);umask
0444
0022
[root@ansible-salve1 ~]# (umask 444;touch 1.txt);umask
0022
[root@ansible-salve1 ~]# ll 1.txt
--w--w--w- 1 root root 0 11月 13 22:12 1.txt
[root@ansible-salve1 ~]# echo $BASHPID
1418
[root@ansible-salve1 ~]# (echo $BASHPID; sleep 3)
1501
{ } 不会开启子shell,在当前shell中运行,会影响当前shell环境
[root@ansible-salve1 ~]# name=mage;{ echo $name;name=wang;echo $name; };echo $name
mage
wang
wang
[root@ansible-salve1 ~]# { umask 444;touch 1.txt; };umask
0444
[root@ansible-salve1 ~]# umask
0444
[root@ansible-salve1 ~]# ll 1.txt
--w--w--w- 1 root root 0 11月 13 22:23 1.txt
[root@ansible-salve1 ~]# echo $BASHPID
1418
[root@ansible-salve1 ~]# { echo $BASHPID; sleep 3; }
1418
[root@ansible-salve1 ~]#
1.6 组合测试条件
1.6.1 第一种方式[ ]
[ EXPRESSION1 -a EXPRESSION2] 并且 ==> 条件1与条件2都为真,结果才为真
[ EXPRESSION1 -O EXPRESSION2] 或 ==> 条件1与条件2只要有一个为真,结果就为真
[ !EXPRESSION1 ] 取反
说明:-a 和 -o 需要使用测试命令执行,[[ ]] 不支持
[root@ansible-salve1 ~]# ll 1.txt
--w--w--w- 1 root root 0 11月 13 22:23 1.txt
[root@ansible-salve1 ~]# FILE=/root/1.txt
[root@ansible-salve1 ~]# [ -f $FILE -a -x $FILE ]
[root@ansible-salve1 ~]# echo $?
1
[root@ansible-salve1 ~]# chmod +x /root/1.txt
[root@ansible-salve1 ~]# [ -f $FILE -a -x $FILE ]
[root@ansible-salve1 ~]# echo $?
0
[root@ansible-salve1 ~]#
1.6.2 第二种方式[[ ]]
COMMAND1 && COMMAND2 #并且,短路与,代表条件性的AND THEN
如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2COMMAND1 || COMMAND2 #或者,短路或,代表条件性的OR ELSE
如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2! COMMAND #非,取反
# 结论:如果&& 和 || 混合使用,&&要在前,||放在后
案例:
[root@ansible-salve1 ~]# id hehao &> /dev/null || useradd hehao # 前面执行不成功,则执行后面的语句
[root@ansible-salve1 ~]# id hehao &> /dev/null && echo "此账户已存在"
此账户已存在
[root@ansible-salve1 ~]#
[root@ansible-salve1 ~]# IP=10.0.0.11;ping -c1 -w1 $IP &> /dev/null && echo $IP is up || echo $IP is down
10.0.0.11 is down
[root@ansible-salve1 ~]# IP=192.168.80.1;ping -c1 -w1 $IP &> /dev/null && echo $IP is up || echo $IP is down
192.168.80.1 is up
[root@ansible-salve1 ~]#
示例:磁盘空间的判断
1.7 使用read命令命令来接受输入
read 是 Shell 内置命令,用来从标准输入中读取数据并赋值给变量。如果没有进行**重定向**,默认就是从键盘读取用户输入的数据;如果进行了重定向,那么可以从文件中读取数据
1.7.1 语法结构
read [option] [variables]
--options表示选项
--variables表示用来存储数据的变量,可以有一个,也可以有多个。
-- options和variables都是可选的,如果没有提供变量名,那么读取的数据将存放到环境变量 REPLY 中。
1.7.2 选项:
| Option | 说明 |
| -a array | 把读取的数据赋值给数组array,从下标0开始 |
| -p prompt | 显示提示信息,提示内容为prompt |
| -t seconds | 设置超时时间,单位为秒。如果用户没能按时完成,返回一个非0的退出状态 |
| -s | 静默模式,不会再屏幕上显示输入的字符。例如:输入密码 |
示例:使用read给多个变量赋值并输出
[root@localhost ~]# vim read.sh
[root@localhost ~]# ./read.sh
请输入你的姓名:yang
Hello, yang !
请输入你的年龄:20
Oh my god, you are so young!
[root@localhost ~]# ./read.sh
请输入你的姓名:yang
Hello, yang !
请输入你的年龄:40
I go you are old hight!
[root@localhost ~]# cat read.sh
#!/bin/bash
read -p "请输入你的姓名:" name
echo "Hello, $name !"
read -p "请输入你的年龄:" age
[ $age -lt 30 ] && echo "Oh my god, you are so young!" || echo "I go you are old hight!"
[root@localhost ~]#
2、流程控制
2.1 条件选择
2.1.1 选择执行if语句
if结构:
[root@localhost ~]# help if
if: if 命令; then 命令; [ elif 命令; then 命令; ]... [ else 命令; ] fi
根据条件执行命令。
执行 "if 命令" 列表。如果退出状态为零,则执行 "then 命令" 列表。
否则按顺序执行每个 "elif 命令" 列表,如果某一个的退出状态为零,则执行
对应的 "then 命令" 列表,然后 if 命令完成。否则,执行 "else 命令"
列表(如果有的话)。整个结构的退出状态是最后一个执行的命令的状态,
或者如果没有一个条件的测试结果为真,则退出状态为零。
退出状态:
返回最后一个执行的命令的状态。
[root@localhost ~]#
2.1.1.1 单分支
if [ 条件判断式 ];then
命令
fi
或者
if [ 条件判断式 ]
then
命令
fi
2.1.1.2 双分支
if [ 条件判断式 ]
then
命令
else
命令
fi
1.1.1.3 多分支
if [ 条件判断式1 ]
then
命令
elif [ 条件判断式2 ]
then
命令
...
...
else
命令
fi
示例:依据BMI参数写出判断语句
[root@localhost ~]# vim info5.sh
[root@localhost ~]# chmod +x info5.sh
[root@localhost ~]# ./info5.sh
请输入身高(m为单位):175
请输入体重(Kg为单位):70
你太瘦了,请注意身体建康
[root@localhost ~]# cat info5.sh
#!/bin/bash
read -p "请输入身高(m为单位):" HIGH
if [[ ! "$HIGH" =~ ^[0-2].?[0-9]{,2}$ ]]
then
echo "请不要输入错误的身高";
exit 1;
fi
read -p "请输入体重(Kg为单位):" WEIGHT
if [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]]
then
echo "请不要输入错误的体重";
exit 1;
fi
BMI=`echo $WEIGHT/$HIGH^2|bc`
if [ $BMI -le 18 ] ;then
echo "你太瘦了,请注意身体建康"
elif [ $BMI -lt 24 ] ;then
echo "身材很棒!"
else
echo "你太胖了,注意节食,加强运动"
fi
[root@localhost ~]#
说明:
* 多个if条件时,逐个条件进行判断,第一次遇见为“真”条件时,执行其分支,而后结束整个if语句
* if语句可嵌套
33万+

被折叠的 条评论
为什么被折叠?



