要使Shell脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。
而专用测试工具是test,test可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。
test测试操作有两种:
- test 条件表达式
- [ 条件表达式 ] #格式二更常用,中括号和表达式之间必须要有至少一个空格隔开,不然会报错
文件测试
格式:
- test 操作符 文件或目录
- [ 操作符 文件或目录 ]
常用的选项
| 选项 | 作用 |
|---|---|
| -e | 测试目录或文件是否存在 |
| -d | 测试是否为目录,还可检测目录是否存在 |
| -f | 测试是否为文件,还可检测文件是否存在 |
| -r | 检测当前用户是否有读的权限 |
| -w | 检测当前用户是否有写的权限 |
| -x | 检测当前用户是否有执行的权限 |
| -s | 检测是否为连接文件 |
#man test可以查看选项
示例:
整数测试
格式:
[ 整数变量1 操作符 整数变量2 ]
test 整数变量1 操作符 整数变量2
常用的操作符
| 操作符 | 作用 | 格式 |
|---|---|---|
| -ec | 等于(Equal) | -- |
| -ne | 不等于(Not Equal) | != |
| -gt | 大于(Greater Than) | \> |
| -lt | 小于(Lesser Than) | \< |
| -le | 小于或等于(Lesser or Equal) | |
| -ge | 大于或等于(Greater or Equal) |
示例:
字符串测试
常用的测试操作符
- =:字符串内容相同
- !=:字符串内容不同,! 号表示相反的意思
- -z:字符串内容为空
- -n:字符是否存在
字符串的常用格式
[ "字符串1" = "字符串2" ] //测试字符串1和字符串2的内容是否相同
[ "字符串1" != "字符串2” ] //测试字符串1和字符串2的内容是否不同
[ -z "字符串" ] //测试字符串是否为空,或者指定的变量是否为空值。(测试字符串的长度是否为零)
[ -n "字符串" ] //测试字符串是否存在,即是否不为空。(测试字符串的长度是否非零)
示例:
abc1=aa
abc2=bb
[ $abc1 = $abc2 ];echo $?
[ $USER = root ];echo $?
[ $USER != root ];echo $?
[ -z $HOME ];echo $?
逻辑测试
逻辑测试用于连接多个测试条件,并返回整个表达式的值。 逻辑测试主要有"逻辑与","逻辑或","逻辑否"三种。
逻辑测试有两种格式
格式一:[ 表达式1 ] 逻辑运算符 [ 表达式2 ] ...
#例:[表达式1] && [表达式2] 等同于 [表达式1 -a 表达式2] 等同于 [[表达式1 && 表达式2]]
#例:[表达式1] || [表达式2] 等同于 [表达式1 -o 表达式2] 等同于 [[表达式1 || 表达式2]]
格式二:命令1 逻辑运算符 命令2 ...
逻辑运算符:
- -a或&& :逻辑与,“而且”的意思,全真才为真。
- -o或|| :逻辑或,“或者”的意思,一真即为真。
- ! :逻辑否。
二元运算符
示例
[ 1 -lt 2 ] && [ 3 -eq 4 ]
echo $?
[ 1 -lt 2 ] || [ 3 -eq 4 ]
echo $?
三元运算符
1、java,C语言
- 条件表达式?a:b
- 当条件表达式为真时,取a值;当条件表达式为假时,取b值。
2、shell
- [ 表达式 ] && a || b
- 当表达式为真时,取a值;当表达式为假时,取b值。
[ 表达式 ] && a //相当于 if语句单分支结构
[ 表达式 ] && a || b //相当于 if语句双分支结构
[ 表达式 ] || b //相当于 if [表达式];else
示例:
vim ping.sh
bash ping.sh 192.168.50.110
#!/bin/bash
ping -c 3 -i 0.5 -w 3 $1 &>/dev/null && echo "$1 is up" || echo "$1 is down"O
vim ping.sh
if语句
单分支结构
格式:
if 判断条件
then 条件成立的分支代码
fi
示例:
df
df |grep /dev/mapper/centos-root |awk '{print $5}'
用脚本的方式查看磁盘使用情况
双分支结构
格式:
if 判断条件
then
条件成立的分支代码
else
条件不成立的分支代码
fi
检测80端口是否在监听,如果是,则提示”网站服务已在运行“,如果否,则启动httpd服务。
vim httpd.sh
#!/bin/bash
netstat -ntap | grep :80 &> /dev/null
if [ $? -eq 0 ];then
echo "网站服务已在运行"
else
if rpm -q httpd &> /dev/null
then
echo "正在启动httpd服务"
systemctl start httpd
else
echo "正在安装并启动httpd服务"
yum install httpd -y &> /dev/null
systemctl start httpd &> /dev/null
fi
fi
bash httpd.sh
rpm -q httpd
bash httpd.sh
case语句
格式
case 变量引用 in
模式1)
命令分支1
;;
模式2)
命令分支2
;;
...
*)
默认命令分支
esac
要注意的东西
case支持glob风格的通配符:
* :任意长度任意字符
? :任意单个字符
[0-9] :指定范围内的任意单个字符
| :“或者”的意思,如: a|b
vim abc.sh
#!/bin/bash
read -p "请输入你的分数(0-100):" grade
case $grade in
100)
echo "牛逼"
;;
[89][0-9])
echo "一点点牛逼"
;;
[67][0-9])
echo "不牛逼"
;;
[0-9]|[1-5][0-9])
echo "不是很牛逼"
;;
*)
echo "输入错了,输入0-100"
bash $0
esac
bash abc.sh