美文网首页
shell编程一

shell编程一

作者: XiaoMing丶 | 来源:发表于2019-01-07 22:14 被阅读0次

    目录

    一、shell脚本中的逻辑判断
    二、文件目录属性判断
    三、if特殊用法
    四、case判断
    五、for循环
    六、while循环
    七、break跳出循环
    八、continue结束本次循环
    九、exit退出整个脚本

    一、shell脚本中的逻辑判断

    • 格式1:if 条件 ; then 语句; fi
      ##条件需要使用方括号 [] 或者 双括号(()) 括起来
    [root@minglinux-01 /usr/local/sbin] a=5 
    [root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]
    > then
    > echo ok
    > fi
    ok
    [root@minglinux-01 /usr/local/sbin] if [ $a -gt 3 ]; then echo ok; fi
    ok
    [root@minglinux-01 /usr/local/sbin] if (($a>3)); then echo ok; fi
    ok
    [root@minglinux-01 /usr/local/sbin] vim if1.sh
    
      1 #!/bin/bash
      2 a=5
      3 if [ $a -gt 3 ];then
      4     echo ok
      5 fi 
    
    [root@minglinux-01 /usr/local/sbin] sh if1.sh 
    ok
    
    • 格式2:if 条件; then 语句; else 语句; fi
    [root@minglinux-01 /usr/local/sbin] vim if2.sh
    
      1 #!/bin/bash
      2 a=2
      3 if [ $a -gt 3 ];then
      4     echo ok
      5 else
      6     echo no
      7 fi
    
    [root@minglinux-01 /usr/local/sbin] sh if2.sh 
    no
    
    • 格式3:if …; then … ;elif …; then …; else …; fi
    [root@minglinux-01 /usr/local/sbin] vim if3.sh
    
      1 #!/bin/bash
      2 a=3
      3 if [ $a -lt 3 ];then
      4     echo "a<3"
      5 elif [ $a -ge 3 ] && [ $a -le 6 ];then
      6     echo "a>=3 && a<=6"
      7 else
      8     echo "a<3"
      9 fi
    
    [root@minglinux-01 /usr/local/sbin] sh if3.sh 
    a>=3 && a<=6
    [root@minglinux-01 /usr/local/sbin] sh -x if3.sh 
    + a=3
    + '[' 3 -lt 3 ']'
    + '[' 3 -ge 3 ']'
    + '[' 3 -le 6 ']'
    + echo 'a>=3 && a<=6'
    a>=3 && a<=6
    

    && 表示当前一条命令成功才执行后面的命令
    || 表示当前一条命令不成功时执行后面的命令
    -lt (小于)、-gt(大于)、-le(小于或等于)、-ge(大于
    或等于)、-eq(等于)、-ne(不等于)

    二、文件目录属性判断

    shell脚本中if还经常用于判断文档的属性,if常用的选项有以下几个:

    [ -f file ]判断是否是普通文件,且存在
    [ -d file ] 判断是否是目录,且存在
    [ -e file ] 判断文件或目录是否存在,存在为真
    [ -b file ] 判断文件是块特殊文件为真
    [ -c file ] 判断文件是字符特殊文件为真
    [ -s file ] 判断文件大小非0时为真
    [ -r file ] 判断文件是否可读,可读为真
    [ -w file ] 判断文件是否可写,可写为真
    [ -x file ] 判断文件是否可执行,可执行为真

    • 示例代码如下
    [root@minglinux-01 ~] if [ -f /root/ ]; then echo ok; fi  #/root/不是文件,不显示ok
    [root@minglinux-01 ~] if [ -d /root/ ]; then echo ok; fi
    ok
    [root@minglinux-01 ~] if [ -e /root/ ]; then echo ok; fi
    ok
    [root@minglinux-01 ~] if [ -e /root/a.txt ]; then echo ok; fi
    [root@minglinux-01 ~] if [ -e /root/1.txt ]; then echo ok; fi
    ok
    [root@minglinux-01 ~] if [ -r /root/1.txt ]; then echo ok; fi
    ok
    [root@minglinux-01 ~] if [ -w /root/1.txt ]; then echo ok; fi
    ok
    [root@minglinux-01 ~] if [ -x /root/1.txt ]; then echo ok; fi
    [root@minglinux-01 ~] ls -l 1.txt 
    -rw-r--r--. 1 root root 2 11月  1 23:47 1.txt
    

    三、if特殊用法

    • if [ -z "$a" ] 判断变量a的值是否为空,空为真
    [root@minglinux-01 ~] wc -l RNG.sh 
    51 RNG.sh
    [root@minglinux-01 ~] a=`wc -l RNG.sh`
    [root@minglinux-01 ~] if [ -z "$a" ]; then echo error; else echo $a; fi
    51 RNG.sh
    [root@minglinux-01 ~] if [ ! -z "$a" ]; then echo error; else echo $a; fi
    error
    
    • if [ -n "$a" ] 判断变量a的值是否为空,非空为真
    [root@minglinux-01 ~] if [ -n "$a" ]; then echo error; else echo $a; fi
    error
    [root@minglinux-01 ~] if [ ! -n "$a" ]; then echo error; else echo $a; fi
    51 RNG.sh
    

    -n和-z只能作用于变量,无法作用于文件

    • if grep -q '123' 1.txt; then 判断文件中是否包含'123'字符串,包含则为真
    [root@minglinux-01 ~] cat 2.txt 
    c b a
    3 2 1
    6 5 4
    [root@minglinux-01 ~] if grep -q 'a' 2.txt; then echo "Yes"; else echo "No"; fi
    Yes
    [root@minglinux-01 ~] if grep -q 'd' 2.txt; then echo "Yes"; else echo "No"; fi
    No
    
    • if [ ! -e file ]; then 判断文件是否存在,不存在为真
    [root@minglinux-01 ~] if [ ! -e ./qwer ]; then echo "不存在"; fi
    不存在
    

    四、case判断

    • 格式:
      case 变量 in
      value1)
      command
      ;;
      value2)
      command
      ;;
      value3)
      command
      ;;
      *)
      command
      ;;
      esac

    在case程序中,可以在条件中使用|,表示或的意思,如:
    2|3)
    command
    ;;

    • 脚本示例
    [root@minglinux-01 /usr/local/sbin] vim case.sh
    ##脚本内容如下:
    #!/bin/bash
    read -p "Please input a number: " n
    if [ -z "$n" ]
    then
        echo "Please input a number."
        exit 1
    fi
    
    n1=`echo $n|sed 's/[0-9]//g'`
    if [ -n "$n1" ]
    then
     echo "Please input a number."
     exit 1
    fi
    
    if [ $n -lt 60 ] && [ $n -ge 0 ]
    then
        tag=1
    elif [ $n -ge 60 ] && [ $n -lt 80 ]
    then
        tag=2
    elif [ $n -ge 80 ]  && [ $n -lt 90 ]
    then
        tag=3
    elif [ $n -ge 90 ] && [ $n -le 100 ]
    then
        tag=4
    else 
        tag=0
    fi
    case $tag in
        1)
        echo "not ok"
            ;;
        2)
            echo "ok"
            ;;
        3)
            echo "ook"
            ;;
        4)
            echo "oook"
            ;;
        *)
            echo "The number range is 0-100."
            ;; 
    esac
    
    [root@minglinux-01 /usr/local/sbin] sh case.sh 
    Please input a number: 100
    oook
    [root@minglinux-01 /usr/local/sbin] sh case.sh 
    Please input a number: 1
    not ok
    [root@minglinux-01 /usr/local/sbin] sh case.sh 
    Please input a number: 
    Please input a number.
    [root@minglinux-01 /usr/local/sbin] sh case.sh 
    Please input a number: 7897
    The number range is 0-100.
    [root@minglinux-01 /usr/local/sbin] echo $?
    0
    

    五、for循环

    • 语法:for 变量名 in 条件; do …; done

     计算1到10数字之和

    [root@minglinux-01 /usr/local/sbin] vim for1.sh
    
      1 #!/bin/bash
      2 sum=0
      3 for i in `seq 1 10`
      4 do
      5     sum=$[$sum+$i]
      6 done
      7 echo $sum
    
    [root@minglinux-01 /usr/local/sbin] sh -x for1.sh 
    + sum=0
    ++ seq 1 10
    + for i in '`seq 1 10`'
    + sum=1
    + for i in '`seq 1 10`'
    + sum=3
    + for i in '`seq 1 10`'
    + sum=6
    + for i in '`seq 1 10`'
    + sum=10
    + for i in '`seq 1 10`'
    + sum=15
    + for i in '`seq 1 10`'
    + sum=21
    + for i in '`seq 1 10`'
    + sum=28
    + for i in '`seq 1 10`'
    + sum=36
    + for i in '`seq 1 10`'
    + sum=45
    + for i in '`seq 1 10`'
    + sum=55
    + echo 55
    55
    
    [root@minglinux-01 /usr/local/sbin] vim for1.sh
    
      1 #!/bin/bash
      2 sum=0
      3 for i in `seq 1 10`
      4 do
      5     echo "$sum + $i"
      6     sum=$[$sum+$i]
      7     echo $sum
      8 done
      9 echo $sum
    
    [root@minglinux-01 /usr/local/sbin] sh for1.sh 
    0 + 1
    1
    1 + 2
    3
    3 + 3
    6
    6 + 4
    10
    10 + 5
    15
    15 + 6
    21
    21 + 7
    28
    28 + 8
    36
    36 + 9
    45
    45 + 10
    55
    55
    

     文件列表循环

    [root@minglinux-01 /usr/local/sbin] vim for2.sh 
    
      1 #!/bin/bash
      2 cd /root/
      3 for i in `ls /root/`
      4 do
      5     if [ -d $i ]
      6     then
      7     ls -d $i
      8     fi
      9 done
    
    [root@minglinux-01 /usr/local/sbin] sh for2.sh 
    dir2
    log
    logs
    rsync
    temp
    
    [root@minglinux-01 /usr/local/sbin] sh -x for2.sh 
    + cd /root/
    ++ ls /root/
    + for i in '`ls /root/`'
    + '[' -d 123.txt ']'
    + for i in '`ls /root/`'
    + '[' -d 123.tzr ']'
    + for i in '`ls /root/`'
    + '[' -d 1.txt ']'
    + for i in '`ls /root/`'
    + '[' -d 2.txt ']'
    + for i in '`ls /root/`'
    + '[' -d 3.txt ']'
    + for i in '`ls /root/`'
    + '[' -d b.txt ']'
    + for i in '`ls /root/`'
    + '[' -d cron.log ']'
    + for i in '`ls /root/`'
    + '[' -d dir2 ']'
    + ls -d dir2
    dir2
    + for i in '`ls /root/`'
    + '[' -d log ']'
    + ls -d log
    log
    + for i in '`ls /root/`'
    + '[' -d logs ']'
    + ls -d logs
    logs
    + for i in '`ls /root/`'
    + '[' -d my.cnf ']'
    + for i in '`ls /root/`'
    + '[' -d qq.txt ']'
    + for i in '`ls /root/`'
    + '[' -d RNG.sh ']'
    + for i in '`ls /root/`'
    + '[' -d rsync ']'
    + ls -d rsync
    rsync
    + for i in '`ls /root/`'
    + '[' -d sim.pid ']'
    + for i in '`ls /root/`'
    + '[' -d temp ']'
    + ls -d temp
    temp
    + for i in '`ls /root/`'
    + '[' -d test.sh ']'
    + for i in '`ls /root/`'
    + '[' -d zabbix-release-3.2-1.el7.noarch.rpm ']'
    
    #for循环时,会以空格或回车作为分隔符
    [root@minglinux-01 /usr/local/sbin] mkdir test
    [root@minglinux-01 /usr/local/sbin] cd test
    [root@minglinux-01 /usr/local/sbin/test] touch 1 2 a\ b 
    [root@minglinux-01 /usr/local/sbin/test] ls -l
    总用量 0
    -rw-r--r-- 1 root root 0 1月   4 20:22 1
    -rw-r--r-- 1 root root 0 1月   4 20:22 2
    -rw-r--r-- 1 root root 0 1月   4 20:22 a b
    [root@minglinux-01 /usr/local/sbin/test] for i in `ls ./`; do echo $i; done
    1
    2
    a
    b
    #a空格b是一个文件,for循环却将a b拆成a、b两个对象
    

    六、while循环

    • 语法: while 条件; do … ; done

    案例一
    需求:每隔半分钟检查一次系统的负载,当系统负载大于10时,发一封邮件给管理员

    [root@minglinux-01 ~] w
     17:31:33 up 1 day, 21:05,  2 users,  load average: 0.00, 0.01, 0.05
    USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
    root     pts/1    192.168.162.1    16:14    1:09m  0.40s  0.15s vim while1.s
    root     pts/2    192.168.162.1    16:22    5.00s  0.15s  0.01s w
    [root@minglinux-01 ~] uptime
     17:31:47 up 1 day, 21:05,  2 users,  load average: 0.00, 0.01, 0.05
    [root@minglinux-01 ~] w |head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1
    0
    [root@minglinux-01 ~] uptime|awk -F 'load average: ' '{print $2}'|cut -d . -f1
    0
    
    ##编写监控脚本如下
    [root@minglinux-01 /usr/local/sbin] vim while1.sh
    
      1 #!/bin/bash
      2 while true  ##使用true和:(冒号)都表示真,进入无限循环
      3 do
      4     load=`w|head -1|awk -F 'load average: ' '{print $2} `
      1 #!/bin/bash
      2 while true
      2 while true
      3 do
      4     load=`w|head -1|awk -F 'load average: ' '{print $2}'|cut -d . -f1`
      5     if [$load -gt 10]
      6     then
      7         /usr/local/sbin/mail.py 331601950@qq.com "load high" "$load"
      8     fi
      9     sleep 30
     10 done
    ##执行脚本
    [root@minglinux-01 /usr/local/sbin] sh -x while1.sh 
    + true
    ++ w  ##第一次
    ++ head -1
    ++ awk -F 'load average: ' '{print $2}'
    ++ cut -d . -f1
    + load=0
    + '[' 0 -gt 10 ']'
    + sleep 30
    + true
    ++ w  ##第二次
    ++ head -1
    ++ awk -F 'load average: ' '{print $2}'
    ++ cut -d . -f1
    + load=0
    + '[' 0 -gt 10 ']'
    + sleep 30
    ···
    ···
    

    若不想让脚本出现意外终止,可以在screen中运行脚本

    案例二
    需求:交互方式输入数字,根据输入数字判断后打印输出

    [root@minglinux-01 /usr/local/sbin] cat while2.sh 
    #!/bin/bash
    while :
    do 
        read -p "请输入一个数字: " n
        if [ -z "$n" ]
        then 
            echo "你需要输入东西"
            continue
        fi
        n1=`echo $n|sed 's/[0-9]//g'`
        if [ ! -z $n1 ]
        then 
            echo "你只能输入一个纯数字"
            continue
        fi 
        break
    done
    echo $n
    
    [root@minglinux-01 /usr/local/sbin] sh while2.sh 
    请输入一个数字: 
    你需要输入东西
    请输入一个数字: 12a
    你只能输入一个纯数字
    请输入一个数字: 123
    123
    

    七、break跳出循环

    [root@minglinux-01 /usr/local/sbin] cat break.sh 
    #!/bin/bash
    for i in `seq 1 5`
    do 
        echo $i
        if [ $i -eq 2 ]   ##数字间比较时使用-eq/-lt/-gt等,字符时比较使用==
        then
            break
        fi 
        echo $i
    done
    echo "ok"
    [root@minglinux-01 /usr/local/sbin] sh break.sh 
    1
    1
    2
    ok
    

    八、continue结束本次循环

    ##忽略continue之下的代码,直接进行下一次循环

    [root@minglinux-01 /usr/local/sbin] cat continue.sh 
    #!/bin/bash
    for i in `seq 1 5`
    do 
        echo $i
        if [ $i -eq 2 ]
        then
            continue 
        fi 
        echo $i
    done
    echo "ok"
    [root@minglinux-01 /usr/local/sbin] sh continue.sh 
    1
    1
    2
    3
    3
    4
    4
    5
    5
    ok
    

    九、exit退出整个脚本

    [root@minglinux-01 /usr/local/sbin] cat exit.sh 
    #!/bin/bash
    for i in `seq 1 5`
    do 
        echo $i
        if [ $i == 2 ]
        then
            exit
        fi 
        echo $i
    done
    echo "ok"
    [root@minglinux-01 /usr/local/sbin] sh exit.sh 
    1
    1
    2
    
    ##通常exit执行后会返回一个状态码,该状态码可自定义,如下
    [root@minglinux-01 /usr/local/sbin] cat exit.sh 
    #!/bin/bash
    for i in `seq 1 5`
    do 
        echo $i
        if [ $i == 2 ]
        then
            exit 1
        fi 
        echo $i
    done
    echo "ok"
    [root@minglinux-01 /usr/local/sbin] sh exit.sh 
    1
    1
    2
    [root@minglinux-01 /usr/local/sbin] echo $?
    1
    

    相关文章

      网友评论

          本文标题:shell编程一

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