shell/流程控制.md

11 KiB
Raw Permalink Blame History

流程控制


一:条件测试

1.语法格式

格式1 test 条件表达式
格式2 [ 条件表达式 ]
格式3 [[ 条件表达式 ]]

2.文件测试

[ -e dir|file ]
[ -d dir ]
[ -f file ]		是否存在,而且是文件
[ -r file ]		当前用户对该文件是否有读权限
[ -x file ]
[ -w file ]

案例

[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.数值比较

[ 1 -gt 10 ]	大于
[ 1 -lt 10 ]	小于
[ 1 -eq 10 ]	等于
[ 1 -ne 10 ]  	不等于
[ 1 -ge 10 ]	大于等于
[ 1 -le 10 ]	小于等于

案例

[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......"
[root@xingdian ~]# [ $(id -u) -eq 0 ] && echo "当前是超级用户"
当前是超级用户
[alice@xingdian ~]$ [ $UID -eq 0 ] && echo "当前是超级用户" || echo "you不是超级用户"
you不是超级用户

4.字符串比较

提示:使用双引号
[root@xingdian ~]# [ "$USER" = "root" ];echo $?
0
[root@xingdian ~]# [ "$USER" == "root" ];echo $?
0

注意:

"":弱引用,可以实现变量和命令的替换
[root@xingdian ~]# x=*
[root@xingdian ~]# echo "$x"
*
'':强引用,不完成变量替换
[root@xingdian ~]# x=*
[root@xingdian ~]# echo '$x'
 $x

5.扩展

[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

案例:

[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 条件测试
then 命令序列
fi

双分支结构

if 条件测试
then 命令序列
else 命令序列
fi

多分支结构

if 条件测试1
then 命令序列

[elif 条件测试2
then 命令序列

elif 条件测试3 
then 命令序列]...

else 命令序列
fi

案例

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循环

语法结构
for i in (取值) 范围{1..20} zhangsan lisi wanger mazi  ${array[*]}
for 变量名 [ in 取值列表 ]
do
	循环体
done
案例一
#!/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
案例二
#!/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
案例三
#!/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
案例
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循环

当条件测试成立(条件测试为假),执行循环体

语法结构
until 条件测试
do
	循环体
done
案例
#!/bin/bash
i=1
until [ "$i" -eq 21 ]
do
    userdel -r user$i
    let i++
done

四:匹配模式

1.语法模式

read -p "请输入你的选项:" num
case num in
1)                     选项  
	命令序列1   命令/if语句/for循环……
	;;
模式2)
	命令序列2
	;;
模式3)
	命令序列3
	;;
*)
	无匹配后命令序列
esac
案例一

确定要继续删除吗 yes/no: " yes

案例二

系统管理工具箱

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.工具箱

#!/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

关键字用于跳出循环,执行循环后面的语句

案例

for i in {1..10}
do
    if [ $i -eq 5 ]
    then
        break
    fi
    echo $i
done
# 输出结果为:
# 1
# 2
# 3
# 4

2.continue

跳过当前循环中的剩余语句,直接进入下一次循环

案例

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.语法格式

[root@xingdiancloud ~]# printf  format-string  [arguments...]
• format-string: 为格式控制字符串
• arguments: 为参数列表
[root@xingdiancloud ~]# echo "Hello, Shell"
Hello, Shell

[root@xingdiancloud ~]# printf "Hello, Shell" 

[root@xingdiancloud ~]# printf "Hello, Shell\n"
Hello, Shell   

2.案例

#!/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.语法格式

格式1echo -e "\033[背景颜色;字体颜色m 要输出的字符 \033[0m"
格式2echo -e "\e[背景颜色;字体颜色m 要输出的字符 \e[0m"

2.案例

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闪烁