• shell编程3-shell选择结构和循环语句


    一.流程控制语句

    1.基本语法结构

    F: false 假
    T : true 真

    if [ condition ];then
    	command
    	command
    fi
    
    [ 条件 ] && command
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请添加图片描述

    if [ condition ];then
    		command1
    	else
    		command2
    fi
    
    [ 条件 ] && command1 || command2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    请添加图片描述

    if [ condition1 ];then
    		command1  结束
    	elif [ condition2 ];then
    		command2   结束
    	else
    		command3
    fi
    注释:
    如果条件1满足,执行命令1后结束;如果条件1不满足,再看条件2,如果条件2满足执行命令2后结束;如果条件1和条件2都不满足执行命令3结束.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    请添加图片描述

    if [ condition1 ];then
    		command1		
    		if [ condition2 ];then
    			command2
    		fi
    	else
    		if [ condition3 ];then
    			command3
    		elif [ condition4 ];then
    			command4
    		else
    			command5
    		fi
    fi
    注释:
    如果条件1满足,执行命令1;如果条件2也满足执行命令2,如果不满足就只执行命令1结束;
    如果条件1不满足,不看条件2;直接看条件3,如果条件3满足执行命令3;如果不满足则看条件4,如果条件4满足执行命令4;否则执行命令5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    请添加图片描述

    2.应用案例

    需求1: 判断主机间是否可以ping通

    思路:
    1. 使用哪个命令实现 ping -c
    2. 根据命令的执行结果状态来判断是否通		$?
    3. 根据逻辑和语法结构来编写脚本(条件判断或者流程控制)
    
    [root@shell ~]# vim ping.sh
    #!/bin/bash
    read -p "请输入需要主机IP地址:" IP
    # 获取需要ping通主机IP地址(定义变量交互式获取)
    ping -c1 $IP &>/dev/nulll
    # ping命令测试主机间互通
    if [ $? -eq 0 ];then
            echo "当前主机与$IP主机间可以ping通"
    else    
            echo "当前主机无法与$IP主机ping通"
    fi   
    [root@shell ~]# source ping.sh 
    请输入需要主机IP地址:10.1.1.14
    当前主机与10.1.1.14主机间可以ping通
    [root@shell ~]# source ping.sh 
    请输入需要主机IP地址:192.168.20.1
    当前主机无法与192.168.20.1主机ping通
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    需求2: 判断一个进程是否存在

    思路:
    1.查看进程的相关命令 ps -ef  pgrep  ps auxf pidof
    2.根据命令的返回状态值来判断进程是否存在  $?
    3.根据逻辑用脚本语言实现
    
    [root@shell ~]# vim process.sh
    #!/bin/bash
    read -p "请输入需要判断的进程名:" process
    # 获取进程名
    pgrep $process &>/dev/null
    # 通过命令查看进程是否存在
    if [ $? -eq 0 ];then
            echo "进程$process存在"
    else
            echo "进程$process不存在"
    fi
    [root@shell ~]# source process.sh 
    请输入需要判断的进程名:bash
    进程bash存在
    [root@shell ~]# source process.sh 
    请输入需要判断的进程名:httpd
    进程httpd不存在
    
    拓展(另一种方法):
    [root@shell ~]# vim process2.sh 
    #!/bin/bash
    #!/bin/bash
    read -p "请输入需要判断的进程名:" process
    # 获取进程名
    pgrep $process &>/dev/null
    [ $? -eq 0 ] && echo "进程$process存在" || echo "进程$process不存在"
    [root@shell ~]# source process2.sh    
    请输入需要判断的进程名:bash
    进程bash存在
    
    pgrep命令:以名称为依据从运行进程队列中查找进程,并显示查找到的进程id
    选项
    -o:仅显示找到的最小(起始)进程号;
    -n:仅显示找到的最大(结束)进程号;
    -l:显示进程名称;
    -P:指定父进程号;pgrep -p 4764  查看父进程下的子进程id
    -g:指定进程组;
    -t:指定开启进程的终端;
    -u:指定进程的有效用户ID。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    需求3:判断网页服务(以nginx为例)是否正常

    思路:
    1.判断网页是否可以正常访问等方法
    [root@shell ~]# vim webtest.sh    
    #!/bin/bash
    curl http://10.1.1.13 &> /dev/null
    [ $? -eq 0 ] && echo "该web服务正常" || echo "该web服务异常"
    [root@shell ~]# systemctl start nginx
    [root@shell ~]# source webtest.sh    
    该web服务正常
    [root@shell ~]# systemctl stop nginx 
    [root@shell ~]# source webtest.sh   
    该web服务异常
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    二.循环语句

    1.for循环

    语法结构

    • 列表循环
      列表for循环:用于将一组命令执行已知的次数,下面给出了for循环语句的基本格式:
    for variable in {list}
         do
              command 
              commanddone
    或者
    for variable in a b c
         do
             command
             command
         done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    例:

    [root@shell ~]# for var in {1..10};do echo $var;done
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@shell ~]# for var in {1..10..2};do echo $var;done
    1
    3
    5
    7
    9
    [root@shell ~]# for var in `seq 10 -2 5`;do echo $var;done 
    10
    8
    6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 不带列表循环
      不带列表的for循环执行时由用户指定参数和参数的个数,下面给出了不带列表的for循环的基本格式:
    for variable
        do
            command 
            commanddone
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    例:

    [root@shell ~]# vim for.sh    
    #!/bin/bash
    for var 
    do
            echo $var
    done
    
    echo "脚本后面有$#个参数"
    [root@shell ~]# source for.sh 1 2 3
    1
    2
    3
    脚本后面有3个参数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 类c风格的for循环,下面给出了基本格式:
    for(( expr1;expr2;expr3 ))
    	do
    		command
    		commanddone
    # expr1:定义变量并赋初值
    # expr2:决定是否进行循环(条件)
    # expr3:决定循环变量如何改变,决定循环什么时候退出
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    例:

    [root@shell ~]# vim for2.sh    
    #!/bin/bash
    for(( i=1;i<=5;i++))
    do
            echo $i
    done
    [root@shell ~]# source for2.sh 
    1
    2
    3
    4
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    循环控制:
    循环体: do…done之间的内容

    • continue:继续;表示循环体内下面的代码不执行,重新开始下一次循环
    • break:打断;马上停止执行本次循环,执行循环体后面的代码
    • exit:表示直接跳出程序
    #!/bin/bash
    for i in {1..5}
    do 
            test $i -eq 2 && break || touch /tmp/file$i
    done    
    echo done 
    [root@shell ~]# source for3.sh 
    done
    [root@shell ~]# ll /tmp/
    total 0
    -rw-r--r-- 1 root root 0 Sep 10 11:39 file1
    drwx------ 2 root root 6 Sep  2 14:04 vmware-root_905-4013330159
    drwx------ 2 root root 6 Sep  1 17:39 vmware-root_960-2999133023
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    小练习:
    1.批量创建5个用户user1-user5,并设置密码为123

    [root@shell ~]# vim user.sh
    #!/bin/bash
    for i in {1..5}
    do      
            useradd user$i
            echo 123|passwd --stdin user$i
    done  
    [root@shell ~]# source user.sh 
    Changing password for user user1.
    passwd: all authentication tokens updated successfully.
    Changing password for user user2.
    passwd: all authentication tokens updated successfully.
    Changing password for user user3.
    passwd: all authentication tokens updated successfully.
    Changing password for user user4.
    passwd: all authentication tokens updated successfully.
    Changing password for user user5.
    passwd: all authentication tokens updated successfully.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2.将局域网内能ping通的IP和不能ping通的IP分类,

    [root@shell ~]# vim pingvc.sh    
    #!/bin/bash
    ip=10.1.1.
    # 定义变量
    for i in {1..15}
    # 循环去ping主机的ip
    do
            ping -c1 $ip$i &>/dev/null
            if [ $? -eq 0 ];then
                    echo "$ip$i is ok" >> /tmp/ip_up.txt
            else
                    echo "$ip$i is down" >> /tmp/ip_down.txt
            fi
    done
    [root@shell ~]# source pingvc.sh 
    [root@shell ~]# cat /tmp/ip_up.txt 
    10.1.1.1 is ok
    10.1.1.13 is ok
    [root@shell ~]# cat /tmp/ip_down.txt
    10.1.1.2 is down
    10.1.1.3 is down
    10.1.1.4 is down
    10.1.1.5 is down
    10.1.1.6 is down
    10.1.1.7 is down
    10.1.1.8 is down
    10.1.1.9 is down
    10.1.1.10 is down
    10.1.1.11 is down
    10.1.1.12 is down
    10.1.1.14 is down
    10.1.1.15 is down
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    总结

    • FOR循环语法结构
    • FOR循环可以结合条件判断和流程控制语句
      • do …done 循环体
      • 循环体里可以是命令集合,再加上条件判断以及流程控制
    • 控制循环语句
      • continue 继续,跳过本次循环,继续下一次循环
      • break 打断,跳出循环,执行循环体外的代码
      • exit 退出,直接退出程序

    2.while循环

    特点:条件为真就进入循环;条件为假就退出循环
    语法结构

    while 表达式
    	do
    		command...
    	done
    	
    while  [ 1 -eq 1 ] 或者 (( 1 > 2 ))
        do
         command
         command
         ...
        done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    例:

    [root@shell ~]# vim while.sh
    #!/bin/bash
    i=1
    while [ $i -le 5 ]
    do
            echo $i
            let i++
    done    
    [root@shell ~]# source while.sh 
    1
    2
    3
    4
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.until循环

    语法结构
    特点:条件为假就进入循环;条件为真就退出循环

    until expression   [ 1 -eq 1 ]  (( 1 >= 1 ))
    	do
    		command
    		command
    		...
    	done
    i=1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    [root@shell ~]# vim until.sh    
    #!/bin/bash
    i=1
    until [ $i -gt 5 ]
    do
            echo $i
            let i++
    done
    [root@shell ~]# source until.sh 
    1
    2
    3
    4
    5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    LeetCode637 二叉树的层平均值
    【单片机原理及应用】第一篇——单片机概述
    Leetcode 118 杨辉三角
    一、爬虫基本概念
    并查集(Union-Find)
    java毕业设计家校通管理系统mybatis+源码+调试部署+系统+数据库+lw
    【送书福利-第二十八期】《AIGC:让生成式AI成为自己的外脑》
    AI创作教程之 如何在本地 PC 上运行稳定的 Diffusion 2.0 (无代码指南)
    OctaneRender界面布局自定义界面教程丨使用教程
    1.4.17 实验17:ASBR
  • 原文地址:https://blog.csdn.net/llllyh812/article/details/126654387