流程控制

作者:行癫(盗版必究) ------ ## 一:条件测试 #### 1.语法格式 ```shell 格式1: test 条件表达式 格式2: [ 条件表达式 ] 格式3: [[ 条件表达式 ]] ``` #### 2.文件测试 ```shell [ -e dir|file ] [ -d dir ] [ -f file ] 是否存在,而且是文件 [ -r file ] 当前用户对该文件是否有读权限 [ -x file ] [ -w file ] ``` 案例 ```shell [root@xingdian ~]# test -d /home [root@xingdian ~]# echo $? 0 [root@xingdian ~]# test -d /home11111 [root@xingdian ~]# echo $? 1 [root@xingdian ~]# [ -d /home ] [root@xingdian ~]# [ ! -d /ccc ] && mkdir /ccc [root@xingdian ~]# [ -d /ccc ] || mkdir /ccc ``` #### 3.数值比较 ```shell [ 1 -gt 10 ] 大于 [ 1 -lt 10 ] 小于 [ 1 -eq 10 ] 等于 [ 1 -ne 10 ] 不等于 [ 1 -ge 10 ] 大于等于 [ 1 -le 10 ] 小于等于 ``` 案例 ```shell [root@xingdian ~]# disk_use=$(df -P |grep '/$' |awk '{print $5}' |awk -F% '{print $1}') [root@xingdian ~]# [ $disk_use -gt 90 ] && echo "war......" [root@xingdian ~]# [ $disk_use -gt 60 ] && echo "war......" ``` ```shell [root@xingdian ~]# [ $(id -u) -eq 0 ] && echo "当前是超级用户" 当前是超级用户 [alice@xingdian ~]$ [ $UID -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户" you不是超级用户 ``` #### 4.字符串比较 ```shell 提示:使用双引号 [root@xingdian ~]# [ "$USER" = "root" ];echo $? 0 [root@xingdian ~]# [ "$USER" == "root" ];echo $? 0 ``` 注意: ```shell "":弱引用,可以实现变量和命令的替换 [root@xingdian ~]# x=* [root@xingdian ~]# echo "$x" * '':强引用,不完成变量替换 [root@xingdian ~]# x=* [root@xingdian ~]# echo '$x' $x ``` #### 5.扩展 ```shell [root@xingdian ~]# var1=111 [root@xingdian ~]# var2= [root@xingdian ~]# //var3变量没有定义 [root@xingdian ~]# echo ${#var1} #显示变量中字符串的个数 3 [root@xingdian ~]# echo ${#var2} 0 [root@xingdian ~]# echo ${#var3} 0 [root@xingdian ~]# [ -z "$var1" ];echo $? //-z 变量字符串为空 1 [root@xingdian ~]# [ -z "$var2" ];echo $? 0 [root@xingdian ~]# [ -z "$var3" ];echo $? 0 [root@xingdian ~]# [ -n "$var1" ];echo $? //-n 变量字符串不为空 0 [root@xingdian ~]# [ -n "$var2" ];echo $? 1 [root@xingdian ~]# [ -n "$var3" ];echo $? 1 ``` 案例: ```shell [root@xingdian ~]# [ "$USER" = "root" ];echo $? 0 [root@xingdian ~]# [ "$USER" = "alice" ];echo $? 1 [root@xingdian ~]# [ "$USER" != "alice" ];echo $? 0 [root@xingdian ~]# [ 1 -lt 2 -a 5 -gt 10 ];echo $? 1 [root@xingdian ~]# [ 1 -lt 2 -o 5 -gt 10 ];echo $? 0 [root@xingdian ~]# [[ 1 -lt 2 && 5 -gt 10 ]];echo $? 1 [root@xingdian ~]# [[ 1 -lt 2 || 5 -gt 10 ]];echo $? 0 [root@xingdian ~]# [ "$USER" = "root" ];echo $? 0 ``` ## 二:条件判断 #### 1.流程控制 ​ 在一个shell脚本中的命令执行顺序称作脚本的流;大多数脚本会根据一个或多个条件来改变它们的流 ​ 流控制命令:能让脚本的流根据条件而改变的命令称为条件流控制命令 ​ exit语句:退出程序的执行,并返回一个返回码,返回码为0正常退出,非0为非正常退出 ​ 条件判断:if代码返回0表示真,非0为假 #### 2.语法结构 单分支结构 ```shell if 条件测试 then 命令序列 fi ``` 双分支结构 ```shell if 条件测试 then 命令序列 else 命令序列 fi ``` 多分支结构 ```shell if 条件测试1 then 命令序列 [elif 条件测试2 then 命令序列 elif 条件测试3 then 命令序列]... else 命令序列 fi ``` 案例 ```shell if [ "$USER" = "root" ] then if [ $UID -eq 0 ] then echo "the user is root" fi elif echo "……" elif echo "……" else echo "the user is not root" echo "正在给用户授权" fi ``` ## 三:循环结构 #### 1.for循环 ##### 语法结构 ```shell for i in (取值) 范围{1..20} zhangsan lisi wanger mazi ${array[*]} for 变量名 [ in 取值列表 ] do 循环体 done ``` ##### 案例一 ```shell #!/bin/bash # ping主机测试 for i in {70..100} do ping -c1 10.30.161.$i &> /dev/null if [ $? -eq 0 ] then echo "10.30.161.$i is up" |tee -a ipup.txt else echo "10.30.161.$i is down" |tee -a ipdown.txt fi done ``` ##### 案例二 ```shell #!/usr/bin/env bash #批量添加账户 for i in {30..40} do useradd user$i && echo "123" | passwd --stdin user$i &>/dev/null if [ $? -eq 0 ];then echo "账户 user$i 添加成功" else echo "账户 user$i 添加失败" fi done ``` ##### 案例三 ```shell #!/usr/bin/env bash #批量删除账户 for i in {20..30} do userdel -r user$i &>/dev/null [ $? -eq 0 ] && echo "账户 user$i 删除成功" || echo "账户 user$i 删除失败" done ``` #### 2.while循环 ​ 不断重复的执行循环体中的语句,直到某个条件成立 ​ 循环次数不一定是固定的 ##### 语法结构 ​ 当条件测试成立(条件测试为真),执行循环体 ``` while 条件测试 do 循环体 done ``` ##### 案例 ```shell echo "please enter a number between 5 and 10 :" read var while [[ $var != 0 ]] do if [ "$var" -lt 5 ] then echo "Too smail , Try again" read var elif [ "$var" -gt 10 ] then echo "Too big , Try again" read var else echo "Congratulation! You are right." exit 0; fi done ``` #### 3.until循环 ​ 当条件测试成立(条件测试为假),执行循环体 ##### 语法结构 ```shell until 条件测试 do 循环体 done ``` ##### 案例 ```shell #!/bin/bash i=1 until [ "$i" -eq 21 ] do userdel -r user$i let i++ done ``` ## 四:匹配模式 #### 1.语法模式 ```shell read -p "请输入你的选项:" num case num in 1) 选项 命令序列1 命令/if语句/for循环…… ;; 模式2) 命令序列2 ;; 模式3) 命令序列3 ;; *) 无匹配后命令序列 esac ``` ##### 案例一 ​ 确定要继续删除吗 yes/no: " yes ##### 案例二 ​ 系统管理工具箱 ```shell Command action h 显示命令帮助 f 显示磁盘分区 d 显示磁盘挂载 m 查看内存使用 u 查看系统负载 q 退出程序 Command (h for help): m total used free shared buffers cached Mem: 7628 840 6788 0 29 378 Swap: 2047 0 2047 ``` #### 2.工具箱 ```shell #!/usr/bin/env bash cat <<-EOF +-------------------------------------------------------------------------+ | System_tools V1.0 | +-------------------------------------------------------------------------+ | a. Stop And Disabled Firewalld. | | b. Disabled SELinux Secure System. | | c. Install Apache Service. | | d. Quit | +-------------------------------------------------------------------------+ EOF printf "\e[1;31m Please input your select: \e[0m" && read var case "$var" in "a") systemctl stop firewalld && systemctl disable firewalld ;; "b") sed -ri s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config ;; "c") yum -y install httpd httpd-tools ;; "d") exit ;; *) printf "请按照上方提供的选项输入!!!\n" ;; esac ``` ## 五:循环控制 #### 1.break ​ 关键字用于跳出循环,执行循环后面的语句 案例 ```shell for i in {1..10} do if [ $i -eq 5 ] then break fi echo $i done # 输出结果为: # 1 # 2 # 3 # 4 ``` #### 2.continue ​ 跳过当前循环中的剩余语句,直接进入下一次循环 案例 ```shell for i in {1..10} do if [ $i -eq 5 ] then continue fi echo $i done # 输出结果为: # 1 # 2 # 3 # 4 # 6 # 7 # 8 # 9 # 10 ``` #### 3.sleep ​ sleep 10 等待10秒,再继续下一操作 ## 六:格式化打印 ​ printf 使用引用文本或空格分隔的参数,外面可以在 printf 中使用格式化字符串,还可以制定字符串的宽度、左右对齐方式等 #### 1.语法格式 ```shell [root@xingdiancloud ~]# printf format-string [arguments...] • format-string: 为格式控制字符串 • arguments: 为参数列表 ``` ```shell [root@xingdiancloud ~]# echo "Hello, Shell" Hello, Shell [root@xingdiancloud ~]# printf "Hello, Shell" [root@xingdiancloud ~]# printf "Hello, Shell\n" Hello, Shell ``` #### 2.案例 ```shell #!/bin/bash printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg printf "%-10s %-8s %-4.2f\n" 张三 男 66.1234 printf "%-10s %-8s %-4.2f\n" 李四 男 48.6543 printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876 ``` #### 3.参数解释 %s 字符串 %f 小数 %d 数字 %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐) %-4.2f 指格式化为小数,其中.2指保留2位小数 \f 换页 \n 换行 \r 回车 ## 七:颜色 ​ shell脚本中echo显示内容带颜色显示,需要使用到-e参数 #### 1.语法格式 ```shell 格式1:echo -e "\033[背景颜色;字体颜色m 要输出的字符 \033[0m" 格式2:echo -e "\e[背景颜色;字体颜色m 要输出的字符 \e[0m" ``` #### 2.案例 ```shell echo -e “\033[30m 黑色字 \033[0m” echo -e “\033[31m 红色字 \033[0m” echo -e “\033[32m 绿色字 \033[0m” echo -e “\033[33m 黄色字 \033[0m” echo -e “\033[34m 蓝色字 \033[0m” echo -e “\033[35m 紫色字 \033[0m” echo -e “\033[36m 天蓝字 \033[0m” echo -e “\033[37m 白色字 \033[0m” echo -e “\033[40;37m 黑底白字 \033[0m” echo -e “\033[41;37m 红底白字 \033[0m” echo -e “\033[42;37m 绿底白字 \033[0m” echo -e “\033[43;37m 黄底白字 \033[0m” echo -e “\033[44;37m 蓝底白字 \033[0m” echo -e “\033[45;37m 紫底白字 \033[0m” echo -e “\033[46;37m 天蓝底白字 \033[0m” echo -e “\033[47;30m 白底黑字 \033[0m” 控制选项: \033[0m:关闭所有属性 \033[1m:高亮显示,加粗 \033[5m:闪烁 ```