条件判断与流程控制
条件判断式
按照文件类型进行判断
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) |
-c 文件 | 判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真) |
-d 文件 | 判断该文件是否存在,并且是否为目录(是目录为真) |
-e 文件 | 判断该文件是否存在(存在为真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 | 判断该文件是否存在,并且是否为符号链接文件(是符号链接文件为真) |
-p 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件为真) |
# 按照文件类型进行判断
test -e ./sh && echo yes || echo no
# 左中括号右和右中括号左 需要有空格
[ -e /root/install.log ]
按照文件权限进行判断
测试选项 | 作用 |
---|---|
-r 文件 | 判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真) |
-w 文件 | 判断该文件是否存在,并且是否该文件拥有写权限(有写权限为真) |
-x 文件 | 判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真) |
-u 文件 | 判断该文件是否存在,并且是否该文件拥有SUID权限(有SUID权限为真) |
-g 文件 | 判断该文件是否存在,并且是否该文件拥有SGID权限(有SGID权限为真) |
-h 文件 | 判断该文件是否存在,并且是否该文件拥有SBit权限(有SBit权限为真) |
# 按照文件权限进行判断
test -w ./sh
# 左中括号右和右中括号左 需要有空格
[ -w /root/install.log ] && echo yes || echo no
两个文件之间进行比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1是否和文件2的inode号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法 |
# 创建文件的硬链接
[root@zdy-centos ~]# ln /root/hello.log /root/hel.log
# 判断两个文件的inode是否相同
[root@zdy-centos ~]# [ /root/hello.log -ef /root/hel.log ] && echo yes || echo no
[root@zdy-centos ~]# test /root/hello.log -ef /root/hel.log && echo yes || echo no
两个整数之间比较
测试选项 | 作用 |
---|---|
整数1 -eq 整数2 | 判断整数1是否和整数2相等(相等为真) |
整数1 -ne 整数2 | 判断整数1是否和整数2不相等(不相等为真) |
整数1 -gt 整数2 | 判断整数1是否大于整数2(大于为真) |
整数1 -gt 整数2 | 判断整数1是否大于整数2(大于为真) |
整数1 -lt 整数2 | 判断整数1是否小于整数2(小于为真) |
整数1 -ge 整数2 | 判断整数1是否大于等于整数2(大于等于为真) |
整数1 -le 整数2 | 判断整数1是否小于等于整数2(小于等于为真) |
# 比较23,22是否相等
[ 23 -eq 22 ] && echo yes || echo no
字符串的判断
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否非空(非空返回真) |
字符串1 == 字符串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字符串1 != 字符串2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
# 双引号 加不加均可
[ -z "$name" ] && echo yes || echo no
[ -n "$name" ] && echo yes || echo no
# == != 左右都需要有空格
[ "$b" == "$a" ] && echo yes || echo no
[ "$b" != "$a" ] && echo yes || echo no
多重条件判断
# a=11,b=22
[root@zdy-centos ~]# [ $a == $b -a $a -lt $b ] && echo yes || echo no
no
[root@zdy-centos ~]# [ $a == $b -o $a -lt $b ] && echo yes || echo no
yes
测试选项 | 作用 |
---|---|
判断1 -a 判断2 | 逻辑与,判断1和判断2都成立,最终的结果才为真 |
判断1 -o 判断2 | 逻辑与,判断1和判断2有一个成立,最终的结果就为真 |
! 判断 | 逻辑非,是原始的判断式取反 |
单分支if语句
if [ 条件判断式 ];then
程序
fi
或
if [ 条件判断式 ]
then
程序
fi
注意:
- if语句使用fi结尾
- [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格
- then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分隔。也可以换行写入,就不需要“;”了。
实例1【判断当前用户是否是root】:
# 查看当前登录用户
[root@zdy-centos ~]# env | grep USER | cut -d "=" -f 2
root
# 判断当前用户是否是root的脚本
#!/bin/bash
if [ $( env | grep USER | cut -d "=" -f 2 ) == root ]
then
echo "当前用户是root"
fi
实例2【判断根分区利用率是否小于90】:
[root@zdy-centos sh]# df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/sda5 26734844 3534028 23200816 14% /
devtmpfs 491220 0 491220 0% /dev
tmpfs 500680 0 500680 0% /dev/shm
tmpfs 500680 6852 493828 2% /run
tmpfs 500680 0 500680 0% /sys/fs/cgroup
/dev/sda3 2086912 72344 2014568 4% /home
/dev/sda1 508588 125224 383364 25% /boot
tmpfs 100136 0 100136 0% /run/user/0
[root@zdy-centos sh]# df -h | grep sda5
/dev/sda5 26G 3.4G 23G 14% /
[root@zdy-centos sh]# df -h | grep sda5 |awk '{print $5}'
14%
[root@zdy-centos sh]# df -h | grep sda5 |awk '{print $5}' | cut -d "%" -f 1
14
# 判断根分区利用率是否小于90%脚本
#!/bin/bash
if [ $( df -h | grep "/$" |awk '{print $5}' | cut -d "%" -f 1) -lt 90 ]
then
echo "根分区使用率不超过90%"
fi
双分支if语句
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
实例【判断输入的是否是一个目录】:
# 脚本
#!/bin/bash
read -t 30 -p 'Please input a dir:' dir
if [ -d $dir ]
then
echo "Input is a dir."
else
echo "Input is not a dir."
fi
[root@zdy-centos sh]# bash dir.sh
Please input a dir:/
Input is a dir.
多分支if语句
# 结束使用
exit 返回值
例如:exit 1
使用$?可以查看脚本的返回值
if [ 条件判断式1 ]
then
当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
当条件判断式2成立时,执行程序2
……
else
当所有条件都不成立时,最后执行此程序
fi
case语句
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值1,则执行程序1
;;
……
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
实例【判断输入的是否是yes,no】
[root@zdy-centos sh]# vi input.sh
read -t 30 -p "Please input yes/no:" cho
case $cho in
yes)
echo Your input is yes!
;;
no)
echo Your input is no!
;;
*)
echo Error!
;;
esac
[root@zdy-centos sh]# bash input.sh
Please input yes/no:no
Your input is no!
[root@zdy-centos sh]# bash input.sh
Please input yes/no:yes
Your input is yes!
[root@zdy-centos sh]# bash input.sh
Please input yes/no:a
Error!
for循环
语法一
for 变量 in 值1 值2 值3 …
do
程序
done
实例【循环输出12345】:
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
实例【批量解压缩脚本】
#!/bin/bash
cd /root/test
ls *.tar.gz >ls.log
for i in $(cat ls.log)
do
tar -zxf $i &>/dev/null
done
rm -rf /root/test/ls.log
语法二
for((初始值;循环控制条件;变量变化))
do
程序
done
实例【计算1+2+3+…+100】
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$(($i+$s))
done
echo The sum of 1+2+3+…+100 is:$s
unset s i
实例【批量添加指定数量的用户】
批量添加
#!/bin/bash
read -p 'Please input username:' -t 30 name
read -p 'Please input the number of users:' -t 30 num
read -p 'Please input the password of users:' -t 30 pass
if [ ! -z $name -a ! -z $num -a ! -z $pass ]
then
y=$(echo $num|sed 's/[0-9]//g')
if [ -z $y ]
then
for(( i=1;i<=$num;i++ ))
do
/usr/sbin/useradd $name$i &>/dev/null
echo $pass|/usr/bin/passwd --stdin $name$i &>/dev/null
done
fi
fi
按照名字批量删除指定数量的用户
#!/bin/bash
read -p 'Please input username:' -t 30 name
read -p 'Please input the number of users:' -t 30 num
if [ ! -z $name -a ! -z $num ]
then
y=$(echo $num|sed 's/[0-9]//g')
if [ -z $y ]
then
for(( i=1;i<=$num;i++ ))
do
/usr/sbin/userdel $name$i &>/dev/null
done
fi
fi
删除除root外的所有用户
#!/bin/bash
for i in $(cat /etc/passwd | grep /bin/bash |grep -v root |cut -d ":" -f 1)
do
userdel $i
done
while循环
while [条件判断式]
do
程序
done
实例【计算1+2+3+…+100】
#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
do
s=$(($s+$i))
i=$(($i+1))
done
echo $s
until循环
until循环,只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。
until [条件判断式]
do
程序
done
实例【计算1+2+3+…+100】
#!/bin/bash
i=1
s=0
until [ $i -gt 100 ]
do
s=$(($s+$i))
i=$(($i+1))
done
echo $s