Day 33 流程控制

一:条件测试

1.语法格式
shell 复制代码
格式1: test 条件表达式
格式2: [ 条件表达式 ]
格式3: [[ 条件表达式 ]]  // 条件表达式中有&&,||和;时使用
2.文件测试
shell 复制代码
[ -e dir|file ] //根据返回值判断,目录或文件是否存在
[ -d dir ]      //根据返回值判断,目录是否存在
[ -f file ]		//根据返回值判断,文件是否存在
[ -r file ]		//根据返回值判断,当前用户对该文件是否有读权限
[ -x file ]     //根据返回值判断,当前用户对该文件是否有执行权限
[ -w file ]     //根据返回值判断,当前用户对该文件是否有写权限

案例

语句①&&语句②:语句①返回值为0(成功)时,执行语句②

语句①||语句②:语句①返回值为非0(失败)时,执行语句②

语句①;语句②:无论语句①返回值为0或非0,都执行语句②

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不是超级用户
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.扩展

-z "$var" \] 根据返回值,判定变量是否为空 \[ -n "$var" \]根据返回值,判定变量是否为非空 ${#var}返回变量中字符串的个数 ```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.语法结构 在每个if条件最后,都需要fi结尾 单分支结构 ```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 ``` ①for循环的条件参数 i 是可以根据取值范围自增的,不需要特地去写i++ ②若想要在取值范围中使用参数,使用步长 seq ```shell for i in `seq 1 $num` //取值范围为1~$num do ... done for i in `seq $num` //取值范围为1~$num do ... done for i in `seq 5 $num` //取值范围为5~$num do ... done ``` ###### 案例一 echo "10.30.161. i i s u p " ∣ t e e − a i p u p . t x t 等价于 e c h o " 10.30.161. i is up" \|tee -a ipup.txt 等价于 echo "10.30.161. iisup"∣tee−aipup.txt等价于echo"10.30.161.i is up" \>\> ipup.txt ```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循环 ​ 不断重复的执行循环体中的语句,直到某个条件成立 ​ 循环次数不一定是固定的 ###### 语法结构 ​ 当条件测试成立时(条件测试为真),执行循环体 ​ 当条件测试不成立时(条件测试为假),跳出循环体 ```shell while 条件测试 do 循环体 done ``` ​ 死循环:使用break或exit可退出循环 ```shell 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 ``` 注意 ①匹配模式以case开始,以esac结束 ②case后跟 $参数名 ③每个模式的名字并不固定,模式为 yes) 时,需要$num值为yes来和模式匹配,固定的只有模式后的半个右括号 ) ④每个模式都要以 ;; 结束 ###### 案例一 ​ 确定要继续删除吗 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.exit 直接跳出循环和程序,不会执行循环后面的语句 ##### 3.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 ``` ##### 4.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:闪烁 ```

相关推荐
矮油0_o2 分钟前
5.好事多磨 -- TCP网络连接Ⅱ
服务器·网络·tcp/ip·网络编程·socket
独隅22 分钟前
针对Ansible执行脚本时报错“可执行文件格式错误”,以下是详细的解决步骤和示例
运维·开发语言·ansible·lua·lua5.4
m0_6779048440 分钟前
Nginx介绍及使用
服务器·nginx
菜鸟xy..43 分钟前
麒麟系统桌面版本v10安装教程
linux·运维·服务器·虚拟机·安装教程·麒麟
什么半岛铁盒1 小时前
存储基石:深度解读Linux磁盘管理机制与文件系统实战
linux·运维·服务器
我命由我123451 小时前
C++ - 头文件基础(常用标准库头文件、自定义头文件、头文件引入方式、防止头文件重复包含机制)
服务器·c语言·开发语言·c++·后端·visualstudio·visual studio code
w23617346011 小时前
Linux常用基础命令应用
linux·服务器·php
别致的影分身1 小时前
Protobuf 的快速使用(四)
服务器·网络·c++
White の algo1 小时前
【Linux系统】linux下的软件管理
linux·运维·服务器
松树戈1 小时前
Ubuntu挂载HDD迁移存储PostgreSQL数据
linux·ubuntu·postgresql