在我们常见的高级语言中都有if
这个关键字,在shell中也有这个关键字,它也是用来做条件判断的。shell中的if的语法格式如下:
一、if语句的基本语法
1、 if
相当于C语言中的if
语句
if condition ; then
command....
...
fi
最后那个fi
必须要写,这也是他语法的一部分。
2、if else
相当于C语言中的if-else
语句
if condtion ; then
command...
....
else
command...
...
fi
3、if else-if else
if condition1 ;then
comand...
...
elif condtion2 ;then # elif分支可以有多个
command...
...
else # else分支只能有一个
command
fi
从语法上来看,shell中的if和C、Java等语言的条件判断语句还是有些许差别的,并且不光是这些差别:
- (1)shell中的else分支如果没有语句,那就不要写出来,这样会报错
- (2)if后的condition一定要是一个能返回true或false的语句,虽然我们常常将1认为是true、0认为是false,但是这里的condition运算结果只能是true或false,否则,即使执行结果是1或0,都会认为condition这个条件是具备的,就不走其他分支了
接下来我们就来学习一下,if的conditon该如何写。
二、Shell条件测试
Shell条件测试有两个命令test
和[
,他们两个的作用是一样的,用于检查某个条件是否成立,可以进行数值、字符和文件三个方面的测试。[
命令和test
命令是两个等价的命令,他们两可以相互替换。
1、数值测试
参数 | 说明 |
---|---|
INTEGER1 -eq INTEGER2 | INTEGER1 is equal to INTEGER2 (两个数都相等为真) |
INTEGER1 -ge INTEGER2 | INTEGER1 is greater than or equal to INTEGER2(大于等于为真) |
INTEGER1 -gt INTEGER2 | INTEGER1 is greater than INTEGER2(大于为真) |
INTEGER1 -le INTEGER2 | INTEGER1 is lss than or equal to INTEGER2(小于等于为真) |
INTEGER1 -lt INTEGER2 | INTEGER1 is less than INTEGER2(小于为真) |
INTEGER1 -ne INTEGER2 | INTEGER1 is not equal to INTEGER2(不等于为真) |
示例:判断两个数大小
#!/bin/bash
#从键盘读入两个数
read -p "input 2 numbers: " num1 num2
if [ $num1 -eq $num2 ]; then #用test命令写:if test $num1 -eq $num2; then
echo "$num1 等于 $num2"
elif [ $num1 -gt $num2 ]; then
echo "$num1 大于 $num2"
else
echo "$num1 小于 $num2"
fi
执行结果:
上面程序中[]
可以使用test命令替换,感兴趣的小伙伴可以自行测试一下。
2、字符串测试
参数 | 说明 |
---|---|
-n STRING | 字符串的长度不为零则为真 |
-z STRING | 字符串的长度为零则为真 |
STRING1 = STRING2 | 两个字符串相等 |
STRING1 != STRING2 | 两个字符串不相等 |
示例:判断输入的两个字符串是否相等
#!/bin/bash
#输入两个字符串
read -p "input 2 strings: " str1 str2
#判断输入的字符是否有空的 字符串为空或没有定义都是0
if [ -n "$str1" ] && [ -n "$str2" ];then
#输入不为空
if [ "$str1" = "$str2" ];then
echo "$str1 equal to $str2"
else
echo "$str1 not equal to $str2"
fi
else
#输入为空,可以要求重新输入
echo "请不要输入空字符串"
read -p "input 2 strings: " str1 str2
fi
exit
执行结果:
3、文件测试
参数 | 说明 |
---|---|
-e FILE|DIR | 如果文件或目录存在则为真(常用) |
-r FILE | 如果文件存在且当前用户可读则为真 |
-w FILE | 如果文件存在且可写则为真 |
-x FILE | 如果文件存在且可执行则为真 |
-s FILE | 如果文件存在且至少有一个字符则为真 |
-d DIR | 如果文件存在并且是目录则为真(常用) |
-f FILE | 如果文件存在且为普通文件(常用) |
-c FILE | 如果文件存在且为字符型特殊文件 |
-b FILE | 如果文件存在且为块特殊文件 |
-L FILE | 文件存在并且是链接文件 |
FILE1 -ef FILE2 | FILE1和FILE2具有相同的设备和inode编号 |
FILE1 -nt FILE2 | FILE1比FILE2新 |
FILE1 -ot FILE2 | FILE1比FILE2旧 |
示例:编写一个脚本,让用户输入一个目录的路径,脚本分别输出该目录下文件和目录的个数。
#!/bin/bash
read -p "Please input an path: " path
if [ -z "$path" ]; then
# 没有输入路劲,不能通过
echo "$0 : can't resolve an empty path"
exit
elif [ ! -d $path ]; then
# 路径错误,不能通过
echo "$0 : cannot access $path: No such file or directory"
exit
else
# 找到路径,进入统计
dirCount=0;
filesCount=0;
for fileName in $(ls $path); do
#这里应该是一个完整的路径,不然就是在判断当前路径下有没有此文件
file=$path/$fileName
if [ -f $file ]; then
let filesCount++
elif [ -d $file ] ; then
let dirCount++
fi
done
echo "$[filesCount+dirCount] files in $path.$filesCount files and $dirCount directors"
fi
执行结果:
4、逻辑运算符
逻辑运算符可以用于连接逻辑表达式的各个条件
参数 | 说明 | 举例 |
---|---|---|
! | 逻辑非运算 | [ ! $fileName = "conf.d" ] 判断文件名知否叫conf.d如果是的话返回false |
-a | 逻辑与运算,遵循逻辑短路原则 | [ -d $file -a `uname -s` = "Linux" ] 判断文件是否是录目录并且当前系统是Linux,如果都是,那么返回true |
-o | 逻辑或运算,遵循逻辑短路原则 | [ $(uname -s) = "Linux" -o $(uname -s) = "FreeBSD" ] 判断当前系统如果是Linux或FreeBSD的话返回true |
&& | 逻辑或,遵循逻辑短路原则 | a=100 b=200 [[ $a gt 50 ]] && [[ $a lt $b ]] 判断a是否大于50并且小于b,如果都满足,返回true |
|| | 逻辑与,遵循逻辑短路原则 | a=100 b=200 [[ $a gt 50 ]] || [[ $b lt 500 ]] 判断a是否大于50或b小于500,如果有一个满足,返回true |
在Shell中if判断中多条件的写法
比如比较a>b 且 a<c,可以的写法如下:
if ((a>b)) && ((a<c)) #这是一种C系语言的写法,在Shell使用(())符号可以支持
或者
if [ $a -gt $b -a $a -lt $c ] #这个其实使用的是shell的额test命令,只不过 [ ]符号是test的等价写法
或者
if [[ $a>$b ]] && [[$a<$c]] #逻辑操作符方式中每个添加单独写,多个条件用逻辑运算符&&、||连接
三、if 练习
1、判断用户是否存在
执行脚本,输入一个用户名,脚本判断此用户是否存在,如果不存在时根据用户输入的Y/N来决定是否创建该用户
#!/bin/bash
set -e
read -p "Please input a username: " username
id $username &>/dev/null
if [ -n "$username" -a "$?" -eq 0 ]; then
echo "$username already exists"
else
read -p "$username not exists.Do you want to create?[Y/N]: " choice
if [ "$choice" = "Y" || "$choice" = "y" ]; then
useradd $username
if [ $? -eq 0 ]; then
echo "$username create success."
fi
else
exit
fi
fi
2、一键检测服务器上docker是否安装、启动
首先脚本判断docker是否安装,如果没有安装就要执行安装;如果已安装,就判断docker是否启动,如果没有启动,就启动docker服务。
#!/bin/bash
#拿到docker的运行状态
docker_status=`systemctl status docker | grep "Active:" | awk '{print $2$3}'`
#检测docker是否运行
if [ -n "$docker_status" -a "$docker_status" = "active(running)" ]; then
echo "docker is running."
else
#检测docker是否安装
rpm -q docker
if [ "$?" -eq 0 ]; then
#docker安装了,启动docker
systemctl start docker
#启动docker中所有容器
containers=$(docker ps -a | awk '{print $1}' | tail -n +2)
for container in containers; do
docker start container $>/dev/null
if [ "$?" -eq 0 ]; then
echo "$container start success!"
else
echo "$continer start failed!"
fi
done
else
#docker没有安装
read -p "package Docker is not installed.Do you want to install?[Y/N]: " choice
if [ "$choice" = "Y" -o "$choice" = "y" ]; then
#安装gcc gcc-c++
yum -y install gcc
yum -y install gcc-c++
#安装docker
yum -y install docker
#配置阿里云加速
echo -e "{\"registry-mirrors\": [\"https://99o2rqoi.mirror.aliyuncs.com\"]}" >/etc/docker/daemon.json
systemctl start docker
systemctl enable docker
echo -e "\nComplete!"
else
echo "exit...."
fi
fi
fi
exit
代码仅供参考,如有不妥之处还望大佬指出,不胜感激!!!