美文网首页
Shell编程、part3

Shell编程、part3

作者: WickJohn | 来源:发表于2019-05-30 17:03 被阅读0次

    本节内容

    1. shell流程控制
    2. for语句
    3. while语句
    4. break和continue语句
    5. case语句
    6. shell编程高级实战

    shell流程控制

    流程控制是改变程序运行顺序的指令。linux shell有一套自己的流程控制语句,其中包括条件语句(if),循环语句(for,while),选择语句(case)。下面我将通过例子介绍下,各个语句使用方法

    if语句

    格式:
    格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi

    1.1 单分支

    -if 条件表达式; then
    -命令
    -fi

    实例:

    #!/bin/bash
     N=10
     if [ $N -gt 5 ]; then
      echo yes
     fi
    
    # bash test.sh
    yes
    

    1.2 双分支

    if 条件表达式; then
      命令
    else
    命令
    fi

    实例1:

    #!/bin/bash
    N=10
    if [ $N -lt 5 ]; then
      echo yes 
    else 
           echo no
    fi
    # bash test.sh
    no
    

    实例2:判断crond进程是否正在运行

    -v: 表示取反
    -c: 即count,取代通常的输出,显示行数

    #!/bin/bash
    NAME=crond
    NUM=$(ps aux | grep $NAME | grep -vc grep) 
    if [ $NUM -eq 1 ]; then
      echo "$NAME running."
    else 
           echo "$NAME is not running!" 
    fi
    

    实例3:检查主机是否在线
    -c:表示发送几次包
    -w:表示等待时间。当试图检测不可达主机时此选项很有用。

    #!/bin/bash 
    if ping -c 1 192.168.1.1 &>/dev/null; then 
          echo "OK."
    else 
          echo "NO!" 
    fi
    

    if 语句可以直接对命令状态进行判断,就省去了获取$?这一步!

    1.3 多分支

    if 条件表达式; then
      命令
    elif 条件表达式; then
      命令
    else 命令
    fi

    当不确定条件符合哪一个时,就可以把已知条件判断写出来,做相应的处理。
    实例1:

    $1:表示接受用户输入参数

    #!/bin/bash
    N=$1
    if [ $N -eq 3 ]; then
      echo "eq 3" 
    elif [ $N -eq 5 ]; then
      echo "eq 5" 
    elif [ $N -eq 8 ]; then
      echo "eq 8"
    else 
          echo "no" 
    fi
    

    如果第一个条件符合就不再向下匹配。

    shell编程之if语句实战案例

    需求:
    1. 完成用户输入文件或者目录的自动复制,并可以实现用户指定复制目标位置。
    2. 用户体验佳。

    #!/bin/bash
    read -p "pls enter a file you want to copy:" file 
    if [ -f $file -o -d $file ];then
            read -p "do you want to copy the $file?(y/n)" sure
         confirm=$(echo ${sure} | tr A-Z a-z) 
            if [ "$confirm" == "y" ];then
                    read -p "where do you want to copy?" dire 
                    if [ -d $dire ];then
                            cp -a $file $dire
                            echo "the $file copied to $dire"
                    else 
                            echo "the $dire is not exists" exit 1 
                     fi
            elif [ "$confirm" == "n" ];then
                    echo "bye"
            else 
                    echo "pls input y or n" 
            fi 
     else echo "the $file is not exists" 
    fi
    

    练习题1:尝试写一个shell简单的计算器,实现加减乘除。
    请输入一个数字: 7
    请输入运算符:+
    请输入第二个数字:7
    7+7=14

    练习题2:输入一个用户,用脚本判断判断该用户是否存在。

    for语句

    格式:for name [ [ in [ word ... ] ] ; ] do list ; done</pre>

    for 变量名 in 取值列表; do
    命令
    done
    或者
    for 变量名 in 取值列表
    do
    命令
    done

    实例1:

    #!/bin/bash 
    for i in {1..3}; do 
            echo $i
    done
    
    # bash test.sh 
    1
    2
    3
    

    实例2:计算100以内偶数和

    #!/bin/bash
    sum=0
    for i in `seq 2 2 100` 
    do 
                  let sum+=$i 
    done
    echo "$sum"
    

    例子3:创建100个用户并设置6位随机密码
    [root@ken ~]# cat test9.sh

    #!/bin/bash
    for i in `seq 10`
    do
    useradd user$i
    pass=`echo $RANDOM | md5sum | cut -c 1-6`
    echo “$pass” | passwd --stdin “user$i”
    echo -e “账户:user$i\n密码:$pass”>> /root/passwd
    done
    

    执行结果:
    [root@ken ~]# cat passwd
    账户:user1
    密码:69a70a
    账户:user2
    密码:444c02
    账户:user3
    密码:6b381f
    账户:user4
    密码:28d8fd

    shell编程之for语句实战案例

    需求:
    1. 批量检查当前教室主机是否在线

    #!/bin/bash
    . /etc/init.d/functions
    ip=192.168.7. 
    for i in {100..150} 
    do
            if ping -c 1 -w 1 $ip$i &>/dev/null;then
                    echo -n "$ip$i在线!" 
                    success
                    echo ""
            else 
                    echo -n "$ip$i不在线!" 
                    failure
                    echo "" 
            fi
    done
    

    练习题1:计算100以内的偶数和
    [root@ken ~]# cat test13.sh

    #!/bin/bash
    sum=0
    for i in `seq 2 2 100`
    do
    let sum+=$i
    done
    echo “$sum”
    

    执行结果:
    [root@ken ~]# bash test13.sh
    2550

    练习题2:判断/root目录下面的文件类型

    #!/bin/bash
    for i in `ls /root`
    do
    type1=`ls -ld $i | cut -c 1`
    if [ “$type1” == “-” ];then
    echo “$i是普通文件”
    elif [ “$type1” == “l” ];then
    echo “$i是连接文件”
    elif [ “$type1” == “d” ];then
    echo “$i是目录”
    else
    echo “该文件类型无法识别”
    fi
    done
    

    执行结果:
    [root@ken ~]# bash error.sh
    error.sh是普通文件
    free_mem是普通文件
    ken是目录
    nohup.out是普通文件
    passwd是普通文件
    t是普通文件
    test10.sh是普通文件
    test11.sh是普通文件
    test12.sh是普通文件
    test13.sh是普通文件
    test15.sh是普通文件
    test16.sh是普通文件
    test18.sh是普通文件
    test19.sh是普通文件

    while语句

    条件为真就进入死循环;条件为假就退出循环
    格式:while list; do list; done
    while 条件表达式; do
    命令
    done

    实例1:

    #!/bin/bash
    N=0
    while [ $N -lt 5 ]; do 
          let N++ 
          echo $N
    done
    
    # bash test.sh 
    1
    2
    3
    4
    5
    

    当条件表达式为 false 时,终止循环。

    实例2:条件表达式为 true,将会产生死循环

    #!/bin/bash 
    while [ 1 -eq 1 ]; do 
          echo "yes" 
    done
    
    也可以条件表达式直接用 true:
    #!/bin/bash 
    while true; do 
          echo "yes" 
    done
    

    死循环有什么作用那?
    可以用来后台运行检测脚本,如下是是一个检测脑裂的脚本
    我们只需要在命令行中输入 nohup bash naolie.sh & 即可在后台持续运行该脚本

    例子1:持续检测内存剩余量,并每隔1分钟输出至一个文件中

    [root@ken ~]# cat test15.sh
    #!/bin/bash
    while true
    do
    mem=`free -h | grep “Mem” | cut -d “M” -f 4 | tr -d ” “`
    echo “$(date “+%F %T”) $mem” >> /root/free_mem
    sleep 2
    done
    

    执行结果:
    [root@ken ~]# tail -f free_mem
    2019-05-31 11:39:11 736
    2019-05-31 11:39:13 736
    2019-05-31 11:39:15 736
    2019-05-31 11:39:17 736
    2019-05-31 11:39:19 736
    2019-05-31 11:39:21 736
    2019-05-31 11:39:23 736

    例子2:持续检测内存剩余量,并每隔1分钟输出至一个文件中,并放在后台运行
    1.&
    [root@ken ~]# bash test15.sh &
    这种写法关闭终端之后脚本退出

    1. nohup
      [root@ken ~]# nohup bash test15.sh &
      这种写法终端关闭没有影响
      关掉脚本:
      ps aux

    要想使用 while 循环逐行读取 a.txt 文件,有三种方式:

    方式 1:

    #!/bin/bash
    cat ./a.txt | while read LINE; do
            echo $LINE
    done
    

    方式2:

    #!/bin/bash 
    while read LINE; do 
            echo $LINE
    done < ./a.txt
    

    方式3:
    exec < ./a.txt # 读取文件作为标准输出
    while read LINE; do
    echo $LINE
    done

    与 while 关联的还有一个 until 语句,它与 while 不同之处在于,是当条件表达式为 false 时才循环,实际使用中比较少,这里不再讲解。

    #!/bin/bash
    n=0 
    until [ $n -eq 5 ] 
    do 
            let n++ 
            echo "$n" 
    done
    

    break和continue语句

    break 是终止循环。
    continue 是跳出当前循环。

    示例 1:在死循环中,满足条件终止循环

    #!/bin/bash
    N=0
    while true; do 
        let N++
            if [ $N -eq 5 ]; then 
                      break 
                 fi
        echo $N
    done
    
    # bash test.sh 1
    2
    3
    4
    

    里面用了 if 判断,并用了 break 语句,它是跳出循环。与其关联的还有一个 continue 语句,它是跳出本次循环。

    示例 2:举例子说明 continue 用法

    #!/bin/bash
    N=0
    while [ $N -lt 5 ]; do 
          let N++
            if [ $N -eq 3 ]; then 
                continue 
            fi
        echo $N
    done
    
    # bash test.sh
    1
    2
    4
    

    当变量 N 等于 3 时,continue 跳过了本次循环,没有执行下面的 echo。

    注意:continue 与 break 语句只能循环语句中使用。
    [root@ken-node1 ~]# cat test.sh

    #!/bin/bash
    st=0
    while true
    do 
        let st++
        if [ $st -eq 5 ];then 
          continue 
        elif [ $st -eq 10 ];then 
              break
        else 
              echo "$st" 
        fi
    
    done
    [root@ken-node1 ~]# bash test.sh 1
    2
    3
    4
    6
    7
    8
    9
    

    break和continue语句

    两个语句只能用在循环语句中!
    break 是终止循环。
    continue 是跳出当前循环。

    例子1:break
    [root@ken ~]# cat test19.sh

    #!/bin/bash
    num=1
    while true
    do
    let num++
    if [ $num -eq 5 ];then
    break
    fi
    echo “$num”
    done
    

    执行结果:
    [root@ken ~]# bash test19.sh
    2
    3
    4

    例子2:continue
    [root@ken ~]# cat test20.sh

    #!/bin/bash
    num=0
    while true
    do
    let num++
    if [ $num -eq 5 ];then
    continue
    fi
    echo “$num”
    done
    

    执行结果:
    [root@ken ~]# bash test20.sh | head
    1
    2
    3
    4
    6
    7
    8
    9
    10
    11

    实际用法:

    #!/bin/bash
    while true
    do
    num=`ss -tnl | grep “80” | wc -l`
    if [ $num -eq 0 ];then
    systemctl restart nginx
    if [ $? -ne 0 ];then
    echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机web服务宕机,技术流ken请尽快上线修复!” | mail -s “152.136.127.116腾讯云主机 web宕机” 1614833188@qq.com
    exit
    else
    echo “`date ‘+%F %T’` 152.136.127.116腾讯云主机 web宕机已自动恢复” | mail -s “152.136.127.116腾讯云主机 web宕机恢复” 1614833188@qq.com
    continue
    fi
    fi
    done
    

    case语句

    case 语句一般用于选择性来执行对应部分块命令。
    case 模式名 in 模式 1)
      命令
      ;;
    模式 2)
      命令
      ;; *)
      不符合以上模式执行的命令
    esac
    每个模式必须以右括号结束,命令结尾以双分号结束,最后一个模式不需要添加;;。

    示例1:根据位置参数匹配不同的模式

    #!/bin/bash case $1 in 
    start)
      echo "start." 
            ;;
    stop)
      echo "stop." 
           ;;
    restart)
      echo "restart." 
            ;; 
    *)
      echo "Usage: $0 {start|stop|restart}" esac
    
    # bash test.sh
    Usage: test.sh {start|stop|restart}
    
    # bash test.sh start
    start.
    
    # bash test.sh stop
    stop.
    
    # bash test.sh restart
    restart。
    

    实例2:

    #!/bin/bash
    case $1 in
    [0-9])
      echo "match number."
      ;;
    [a-z])
      echo "match letter."
      ;;
    '-h'|'--help')
      echo "help"
      ;;
    *)
      echo "Input error!"
      exit
    esac
    
    # bash test.sh 1
    match number.
    
    # bash test.sh a
    match letter.
    
    # bash test.sh -h
    help
    
    # bash test.sh --help
    help
    

    模式支持的正则有:*、?、[ ]、[.-.]、|。后面有章节单独讲解 Shell 正则表达式。

    shell编程高级实战

    实战1:写一个猜数字的小游戏

    要求:

    1. 猜对退出
    2. 数字随机
    3. 使用体验佳

    #!/bin/bash
    clear
    num=`echo $RANDOM`
    count=0
    while true
    do
            let count++
            read -p "pls enter a num you guess:" guessnum
            if [ $guessnum -lt $num ]; then
                    echo "the num is so smaller!"
            elif [ $guessnum -gt $num ];then
                    echo "the num is so bigger!"
            elif [ $guessnum -eq $num ];then
                    echo "right!wonderful! " 
                    break
            else
                    echo "good bye"
                    exit
            fi
    done
    

    echo -e "\033[36myou guess $count times\033[0m" #-e允许对下面列出的加反斜线转义的字符进行解释.

    实战2:检测当前教室在线IP地址

    要求:

    1.显示美观

    #!/bin/bash
    . /etc/init.d/functions
    ip=172.20.10.
    for i in {1..255}
    do
            if ping -c 1 $ip$i &>/dev/null ;then
                    echo -n "$ip$i"    #-n表示不输出行尾的换行符
                    success
                    echo ""
            else
                    echo -n "$ip$i"
                    failure
                    echo ""
            fi
    done
    

    实战3:检查软件包是否安装

    要求:

    1.用户输入软件名即可进行查询

    #!/bin/bash
    read -p "pls enter a softname:" softname
    if rpm -q $softname &>/dev/null ;then
            echo "the $softname is already installed"
    else
            echo "the $softname" is not installed
    fi
    

    实战4:打印九九乘法表

    #!/bin/bash
    for i in `seq 9`
    do
            for a in `seq 9`
            do
                    if [ $a -le $i ];then
                            echo -n "$a*$i=$(($i*$a)) "
                    fi
            done
            echo ""
    done
    

    补充练习题

    1.实现简单计算器(加减乘除)

    #!/bin/bash
    read -p "请输入第一个数字:" a
    read -p "请输入运算符[+-*/]:" b
    read -p "请输入第二个数字:" c
    if [ -n "$a" -a -n "$b" -a -n "$c" ];then
            if [ "$b" == "+" ];then
                    echo "$a+$c=$(($a+$c))"
            elif [ "$b" == "-" ];then
                    echo "$a-$c=$(($a-$c))"
            elif [ "$b" == "*" ];then
                    echo "$a*$c=$(($a*$c))"
            elif [ "$b" == "/" ];then
                    echo "$a/$c=$(($a/$c))"
            else
                    echo "请输入+—*%"
            fi
    else
            echo "请按照要求输入内容!"
    fi
    
    1. 批量创建100个以数字开头的文件,并每隔一秒钟输出到终端
    #!/bin/bash
    for i in {1..100}
    do
            touch ${i}.txt
            echo "${i}.txt"
            sleep 1
    done
    

    3.动态持续监测本机linux系统内存剩余量(仅显示数值),并在终端输出

    #!/bin/bash
    while true
    do
            mem=`free -h | grep "Mem" | cut -d "M" -f 4 | tr -d " "`
            echo $mem
            sleep 1
    
    done
    

    课后练习题

    写一个脚本: 实现自动化一键部署NFS服务器端和客户端
    第二个脚本:实现批量化检测当前教室主机在线状况,在线主机保存至一个文件中
    第三个脚本:实现批量化创建100个用户,并创建8位随机密码,且可登陆
    第四个脚本:找出系统中含有某个关键词的文件,并输出到终端,关键词用户输入指定
    第五个脚本:批量判断当前目录下所有文件类型

    补充:shell练习题

    1. 每一秒钟输出/root下的文件至屏幕
    2. 打印出包含某个关键词的文件(关键词执行脚本时接收)
    3. 统计系统中以.sh结尾的文件总大小,输出结果以kb为单位

    参考答案:

    #!/bin/bash
    for file in `ls /root`
    do
            echo $file
            sleep 1
    done
    
    #!/bin/bash
    key=$1
    for file in `find / -type f`
    do
            grep "$key" $file &>/dev/null
            if [ $? -eq 0 ];then
                    echo $file
                    sleep 1
            fi
    done
    
    #!/bin/bash
    sum=0
    for size in `find /root -name "*.sh" -exec ls -l {} \; | cut -d " " -f 5`
    do
            let sum+=$size
    done
    echo "$((sum/1024))kb"
    

    相关文章

      网友评论

          本文标题:Shell编程、part3

          本文链接:https://www.haomeiwen.com/subject/tadvtctx.html