【Linux】【Shell】Shell 编程中的条件判断与流程控制

研究学习 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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值