研究学习 Linux Shell 的系列文章.
这篇文章主要讲 Shell 编程中的条件判断与流程控制.
文章目录
1. 条件判断式语句
两种判断格式:
test 判断式
[ 判断式 ]
1.1 按照文件类型进行判断
测试选项 | 作用 |
---|---|
-b 文件 | 判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) |
-c 文件 | 判断该文件是否存在,并且是否为字符设备文件(是字符设备文件为真) |
-d 文件 | 判断该文件是否存在,并且是否为目录文件(是目录为真) |
-e 文件 | 判断该文件是否存在(存在为真) |
-f 文件 | 判断该文件是否存在,并且是否为普通文件(是普通文件为真) |
-L 文件 | 判断该文件是否存在,并i企鹅是否为符号链接文件(是符号链接文件为真) |
-p 文件 | 判断该文件是否存在,并且是否为管道文件(是管道文件为真) |
-s 文件 | 判断该文件是否存在,并且是否为非空(非空为真) |
-S 文件 | 判断该文件是否存在,并且是否为套接字文件(是套接字文件为真) |
两种判断格式:
test -e /root
[ -e /root ]
使用预定义变量查看结果
[root@cloudvm ~]# [ -d /root ]
[root@cloudvm ~]# echo $?
0
[root@cloudvm ~]# [ -d /aaaaa ]
[root@cloudvm ~]# echo $?
1
使用运算符查看结果
[root@cloudvm ~]# [ -d /root ] && echo "yes" || echo "no"
yes
[root@cloudvm ~]# [ -d /aaaaa ] && echo "yes" || echo "no"
no
1.2 按照文件权限进行判断
测试选项 | 作用 |
---|---|
-r 文件 | 判断该文件是否存在,并且是否该文件拥有读权限(有读权限为真) |
-w 文件 | 判断该文件是否存在,并且是否该文件哟ing有执行权限(有执行权限为真) |
-x 文件 | 判断该文件是否存在,并且是否该文件拥有执行权限(有执行权限为真) |
-u 文件 | 判断该文件是否存在,并且是否该文件拥有 SUID 权限(有 SUID 权限为真) |
-g 文件 | 判断该文件是否存在,并且是否该文件拥有 SGID 权限(有 SGID 权限为真) |
-k 文件 | 判断该文件是否存在,并且是否该文件拥有 SBit 权限(有 SBit 权限为真) |
1.3 两个文件之间进行比较
测试选项 | 作用 |
---|---|
文件1 -nt 文件2 | 判断文件1的修改时间是否比文件2的新(如果新则为真) |
文件1 -ot 文件2 | 判断文件1的修改时间是否比文件2的旧(如果旧则为真) |
文件1 -ef 文件2 | 判断文件1是否和文件2的 Inode 号号一致,可以理解为两个文件是否为同一个文件. 这个判断用于判断硬链接是很好的方法. |
[root@cloudvm ~]# ln /root/student.txt /tmp/stu
[root@cloudvm ~]# [ /root/student.txt -ef /tmp/stu ] && echo yes || echo no
yes
[root@cloudvm ~]# [ /root/student.txt -ef /tmp/sta ] && echo yes || echo no
no
1.4 两个整数之间进行比较
测试选项 | 作用 |
---|---|
整数1 -eq 整数2 | 判断整数1是否和整数2相等(相等为真) |
整数1 -ne 整数2 | 判断整数1是否和整数2不相等(不相等为真) |
整数1 -gt 整数2 | 判断整数1是否大于整数2(大于为真) |
整数1 -lt 整数2 | 判断整数1是否小于整数2(小于为真) |
整数1 -ge 整数2 | 判断整数1是否大于等于整数2(大于等于为真) |
整数1 -le 整数2 | 判断整数1是否小于等于整数2(小于等于为真) |
[root@cloudvm ~]# [ 23 -ge 22 ] && echo yes || echo no
yes
[root@cloudvm ~]# [ 23 -le 22 ] && echo yes || echo no
no
1.5 字符串的判断
测试选项 | 作用 |
---|---|
-z 字符串 | 判断字符串是否为空(为空返回真) |
-n 字符串 | 判断字符串是否为非空(非空返回真) |
字串1 == 字串2 | 判断字符串1是否和字符串2相等(相等返回真) |
字串1 != 字串2 | 判断字符串1是否和字符串2不相等(不相等返回真) |
[root@cloudvm ~]# name=Lucy
[root@cloudvm ~]# [ -z "$name" ] && echo yes || echo no
no
[root@cloudvm ~]# [ -z $name ] && echo yes || echo no
no
[root@cloudvm ~]# name=""
[root@cloudvm ~]# [ -z "$name" ] && echo yes || echo no
yes
[root@cloudvm ~]# [ -z $name ] && echo yes || echo no
yes
[root@cloudvm ~]# aa=11
[root@cloudvm ~]# bb=22
[root@cloudvm ~]# [ "$aa" == "$bb" ] && echo yes || echo no
no
[root@cloudvm ~]# [ "$aa" -eq "$bb" ] && echo yes || echo no
no
1.6 多重条件判断
测试选项 | 作用 |
---|---|
判断1 -a 判断2 | 逻辑与,判断1和判断2都成立,最终的结果才为真 |
判断1 -o 判断2 | 逻辑或,判断1和判断2有一个成立,最终的结果就为真 |
! 判断 | 逻辑非,使原始的判断式取反 |
[root@cloudvm ~]# aa=22
[root@cloudvm ~]# bb=22
[root@cloudvm ~]# [ "$aa" == "$bb" -a "$aa" -gt 11 ] && echo yes || echo no
yes
2. 单分支 if 语句
格式:
if [ 条件判断式 ];then
程序
fi
或
if [ 条件判断式 ]
then
程序
fi
eg1.sh
:例 1 判断登陆的用户是否root
#!/bin/bash
test=$(env | grep "USER" | cut -d "=" -f 2)
if [ "$test" == root ]
then
echo "Current user is root."
fi
[root@cloudvm ~]# ./eg1.sh
Current user is root.
eg2.sh
:例 2 判断分区使用率
#!/bin/bash
test=$(df -h | grep sda3 | awk '{print $5}' | cut -d "%" -f 1)
if [ "$test" -ge "5" ]
then
echo "/ if full"
fi
[root@cloudvm ~]# ./eg2.sh
/ if full
3. 双分支 if 语句
格式:
if [ 条件判断式 ]
then
条件成立时,执行的程序
else
条件不成立时,执行的另一个程序
fi
eg3.sh
:例3判断路径是否为目录
#!/bin/bash
read -t 30 -p "Please input a dir: " dir
if [ -d "$dir" ]
then
echo "is dir"
else
echo "not dir"
fi
[root@cloudvm ~]# ./eg3.sh
Please input a dir: /root
is dir
[root@cloudvm ~]# ./eg3.sh
Please input a dir: /abcdd
not dir
eg4.sh
:例4监控 httpd 是否运行,如果宕机重新启动
#!/bin/bash
test=$(ps aux | grep httpd | grep -v grep)
if [ -n "$test" ]
then
echo "httpd is running!"
else
echo "httpd is not running!"
echo "restarting..."
systemctl start httpd.service &> /dev/null
fi
[root@cloudvm ~]# systemctl start httpd.service
[root@cloudvm ~]# ./eg4.sh
httpd is running!
[root@cloudvm ~]# systemctl stop httpd.service
[root@cloudvm ~]# ./eg4.sh
httpd is not running!
restarting...
4. 多分支 if 语句
if [ 条件判断式1 ]
then
当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
then
当条件判断式2成立时,执行程序2
...省略更多条件...
else
当所有条件都不成立时,最后执行此程序
fi
eg5.sh
:例5用 Shell 写一个简单计算器.
#!/bin/bash
read -t 30 -p "Please input num1: " num1
read -t 30 -p "Please input num2: " num2
read -t 30 -p "Please input an operator: " op
if [ -n "$num1" -a -n "$num2" -a -n "$op" ]
then
test1=$(echo $num1 | sed 's/[0-9]//g')
test2=$(echo $num2 | sed 's/[0-9]//g')
if [ -z "$test1" -a -z "$test2" ]
then
if [ "&op" == '+' ]
then
value=$(($num1+$num2))
elif [ "&op" == '-' ]
then
value=$(($num1-$num2))
elif [ "$op" == '*' ]
then
value=$(($num1*$num2))
elif [ "$op" == '/' ]
then
value=$(($num1/$num2))
else
echo "Please enter a valid symbol。"
exit 10
fi
else
echo "Please enter a valid number."
exit 11
fi
else
echo "Please input a number."
exit 12
fi
echo "$num1 $op $num2 = $value"
[root@cloudvm ~]#
[root@cloudvm ~]# ./eg5.sh
Please input num1: 10
Please input num2: 2
Please input an operator: *
10 * 2 = 20
[root@cloudvm ~]# ./eg5.sh
Please input num1:
Please input num2:
Please input an operator:
Please input a number.
eg6.sh
:例6判断路径是什么文件
#!/bin/bash
read -p "Please input a filename: " filepath
if [ -z "$filepath" ]
then
echo "Error, please input a filename."
exit 1
elif [ ! -e "$filepath" ]
then
echo "Your input is not a file."
exit 2
elif [ -f "$filepath" ]
then
echo "$filepath is a regulare file."
elif [ -d "$filepath" ]
then
echo "$filepath is a dirctory."
else
echo "$filepath is another kind file."
fi
[root@cloudvm ~]# ./eg6.sh
Please input a filename:
Error, please input a filename.
[root@cloudvm ~]# ./eg6.sh
Please input a filename: /root
/root is a dirctory.
[root@cloudvm ~]# ./eg6.sh
Please input a filename: abc.txt
abc.txt is a regulare file.
[root@cloudvm ~]# ./eg6.sh
Please input a filename: /dev/sda1
/dev/sda1 is another kind file.
ctrl + 退格
删除输入.
5. 多分支 case 语句
case 语句和 if…elif…else 语句一样都是多分支条件语句,不过和 if 多分支条件语句不同的是,case语句只能判断一种条件关系,而 if 语句可以判断多种条件关系.
case $变量名 in
“值1”)
如果变量的值等于1,则执行程序1
;;
“值2”)
如果变量的值等于值2,则执行程序2
;;
...省略其它分支...
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
eg7.sh
:例 7 判断输入
#!/bin/bash
read -p "Please choose yes/no: " -t 30 cho
case $cho in
"yes")
echo "Your choose is yes!"
;;
"no")
echo "Your choose is no!"
;;
*)
echo "Your choose is error!"
;;
esac
[root@cloudvm ~]# ./eg7.sh
Please choose yes/no: yes
Your choose is yes!
[root@cloudvm ~]# ./eg7.sh
Please choose yes/no: no
Your choose is no!
[root@cloudvm ~]# ./eg7.sh
Please choose yes/no:
Your choose is error!
6. for 循环
语法格式 1 :
for 变量 in 值1 值2 值3 ...
do
程序
done
eg8.sh
:例 8 循环打印变量
#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
[root@cloudvm ~]# ./eg8.sh
1
2
3
4
5
eg9.sh
:例 9 打印目录下的所有路径
#!/bin/bash
ls / > pathes.txt
for i in $(cat pathes.txt)
do
echo $i
done
rm -rf pathes.txt
[root@cloudvm ~]# ./eg9.sh
bin
boot
dev
etc
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
语法格式 2:
for ((初始值; 循环控制条件; 变量变化))
do
程序
done
eg10.sh
:例 10 计算 1 到 100 的累加和
#!/bin/bash
s=0
for ((i=1; i<=100; i=i+1))
do
s=$(($s+$i))
done
echo "1+2+3+...+100=$s"
[root@cloudvm ~]# ./eg10.sh
1+2+3+...+100=5050
eg11.sh
:例 11 批量添加用户
#!/bin/bash
read -p "Please input user name: " -t 30 name
read -p "Please input the number users: " -t 30 num
read -p "Please input the password of users: " -t 30 passwd
if [ ! -z "$name" -a ! -z "$num" -a ! -z "$passwd" ]
then
y=$(echo $num | sed 's/[0-9]//g')
if [ -z "$y" ]
then
for ((i=1; i<=$num; i=i+1))
do
/usr/sbin/useradd $name$i &> /dev/null
echo $passwd | /usr/bin/passwd --stdin $name$i &> /dev/null
done
fi
fi
[root@cloudvm ~]# ./eg11.sh
Please input user name: lucy
Please input the number users: 30
Please input the password of users: 123
eg12.sh
:例 12 批量删除用户
#!/bin/bash
for i in $(cat /etc/passwd | grep /bin/bash | grep -v root | grep -v lucifer | cut -d ":" -f1)
do
userdel -r $i
done
[root@cloudvm ~]# ./eg12.sh
7. while 循环和 until 循环
while 循环是不定循环,也称作条件循环. 只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止. 这就和 for 的固定循环不太一样了.
while 循环语法格式:
while [ 条件判断式 ]
do
程序
done
eg13.sh
:例 13 计算 1 到 100 累加和
#!/bin/bash
i=0
s=0
while [ $i -le 100 ]
do
s=$(($s+$i))
i=$(($i+1))
done
echo "1+2+3+...+100=$s"
[root@cloudvm ~]# ./eg13.sh
1+2+3+...+100=5050
until 循环,和 while 循环相反,until 循环时只要条件判断式不成立则进行循环,并执行循环程序. 一旦循环条件成立,则终止循环.
until 循环语法格式:
until [ 条件判断式 ]
do
程序
done
eg13.sh
:例 14 计算 1 到 100 的累加和
#!/bin/bash
i=0
s=0
until [ $i -gt 100 ]
do
s=$(($s+$i))
i=$(($i+1))
done
echo "1+2+3+...+100=$s"
[root@cloudvm ~]# ./eg14.sh
1+2+3+...+100=5050