• 模块二、shell脚本逻辑结构


    七、if结构条件句知识与实践

    (一)if条件句单双分支语法

    1、单分支
    if 条件
       then
       指令
    fi
    2、双分支
    if 条件
       then
       指令
    else
       指令集2
    fi
    

    (二)if条件句多分支语句

    if 条件1
       then
       指令1
    elif 条件2
       then
       指令2
    elif 条件3
       then
       指令3
    else
       指令4
       
    fi 
    

    实例:

    如果不存在目录/backup,则创建。
    [root@centos6-kvm3 scripts]# cat 07-01.sh
    #!/bin/bash
    path="/backup"
    [ -d $path ] || mkdir $path -p
    
    if [ -d $path ]
    then
       :
    else
      mkdir $path -p
    fi
    
    if [ !-d $path]
    then
      mkdir $path -p
    fi
    [root@centos6-kvm3 scripts]#
    
    
    
    
    开发shell脚本判断内存是否充足,如果小于100,提示不足,如果大于100提示充足。
    [root@centos6-kvm3 scripts]# cat 07-02.sh 
    #!/bin/bash
    mem=`free -m | awk 'NR==3{print $NF}'`
    if [ $mem -lt 100 ]
    then
       echo "内存不充足!"
    else
       echo "内存充足!"
    fi
    [root@centos6-kvm3 scripts]# 
    

    判断两个整数大小:

    [root@centos6-kvm3 scripts]# cat 07-03.sh
    #!/bin/bash
    read -p "请输入两个整数:" a b
    expr $a + $b + 1 &>/dev/null
    if [ $? -ne 0 ]
    then
       echo "请输入两个整数。"
       exit 0
    fi
    if [ -z "$b" ]
    then
      echo "请输入两个整数。"
      exit 1
    fi
    
    if [ $a -lt $b ]
    then
       echo "$a小于$b"
    elif [ $a -gt $b ]
    then
       echo "$a大于$b"
    else
       echo "$a等于$b"
    fi
    
    [root@centos6-kvm3 scripts]# 
    如果使用传参方式:
    [$# -ne 2 ]判断参数是否为两个。
    

    打印一个安装菜单:

    [root@centos6-kvm3 scripts]# cat 07-04.sh
    #!/bin/bash
    cat <<EOF
    1.install lamp
    2.install lnmp
    3.exit
    EOF
    read -p "请输入一个数字{1|2|3}:" n
    expr $n + 2 &>/dev/null
    if [ $? -ne 0 ]
    then
       echo "usage:$0{1|2|3}"
       exit 0
    fi
    
    if [ $n -eq 1 ]
    then
       echo "install lamp"
    elif [ $n -eq 2 ]
    then
       echo "install lnmp"
    elif [ $n -eq 3 ]
    then
       echo "exit"
    else
       echo "usage:$0{1|2|3}"
    fi
    [root@centos6-kvm3 scripts]# 
    

    八、函数知识与实践

    (一)shell函数语法

    第一种语法 第二种语法 第三种语法
    function 函数名(){ } function 函数名 {} 函数名() { }

    实例

    [root@centos6-kvm3 scripts]# cat 08-01.sh
    #!/bin/bash
    function oldboy(){
    echo "i am $1 teacher"
    
    }
    function oldgirl {
    echo "i am $1 teacher"
    }
    
    test() {
    echo "this is $1"
    }
    
    oldboy $1
    oldgirl $2
    test $3
    [root@centos6-kvm3 scripts]# bash 08-01.sh oldboy oldgirl test
    i am oldboy teacher
    i am oldgirl teacher
    this is test
    [root@centos6-kvm3 scripts]# 
    

    实例:检测web网站是否正常

    wget 命令:

    --spider 模拟爬虫

    -q 安静访问

    -o /dev/null 不输出

    -T --timeout 超时时间

    -t --tries 重试次数

     wget --spider -T 5 -q -o /dev/null -t 2 www.baidu.com
     echo $?
    

    curl命令:

    -I 查看响应头

    -s 安静的

    -o /dev/null 不输出

    -w%{http_code} 返回状态码

    [root@centos6-kvm3 scripts]# curl -I -s -o /dev/null -w "%{http_code}
    " www.baidu.com
    200
    [root@centos6-kvm3 scripts]# 
    

    案例:

    [root@centos6-kvm3 scripts]# cat 08-02.sh
    #!/bin/bash
    function usage(){
    echo "usage:$0 url"
    exit 1
    }
    function url_check {
    wget -q -o /dev/null -T 5 -t 3 $1
    if [ $? -eq 0 ]
    then
       echo "$1 is ok!"
    else
       echo "$1 is fail!"
    fi
    }
    main(){
    if [ $# -ne 1 ]
    then
       usage
    else
       url_check $1
    fi
    }
    
    main $*
    
    [root@centos6-kvm3 scripts]# 
    

    九、case结构条件句应用时间

    (一)case语法结构

    case结构条件句相当于多分支if条件语句,但是它比这些条件句看起来更规范工整,常被用于实现系统服务脚本等应用场景中。

    case语句的语法结构:

    case "变量" in
          值1)
              指令1
              ;;
           值2)
              指令2
              ;;
           值3)
              指令3
              ;;
            *)
              指令4
     esac
    

    (二)实例1:

    [root@centos6-kvm3 scripts]# cat 09-03.sh
    #!/bin/bash
    cat <<EOF
    1.install lnmp
    2.install lamp
    3.exit
    EOF
    read -p "请输入一个数字{1|2|3}:" num
    expr $num + 2 &>/dev/null
    if [ $? -ne 0 ]
    then
      echo "usage:$0{1|2|3}"
      exit 1
    fi
    case $num in
         1)
         echo "install lnmp"
         ;;
         2)
         echo "install lamp"
         ;;
         3)
         echo "exit"
         exit
         ;;
         *)
         echo "usage:$0{1|2|3}"
         exit 1
    esac
    
    
    [root@centos6-kvm3 scripts]# 
    

    (三)实例2:

    当用户输入对应的数字选择水果的时候,告诉他选择的水果是什么,并给水果单词加上一种颜色(随意),要求用case语句实现。

    内容的颜色用数字表示,范围为30-37,每个数字代表一种颜色。
    echo -e "33[30m 黑色字oldboy trainning 33[0m" #<==30m表示黑色字。
    echo -e "33[31m 红色字oldboy trainning 33[0m" #<==31m表示红色字。
    echo -e "33[32m 绿色字oldboy trainning 33[0m" #<==32m表示绿色字。
    echo -e "33[33m 棕色字oldboy trainning 33[0m" #<==33m表示棕色字(brown),和黄色字相近。
    echo -e "33[34m 蓝色字oldboy trainning 33[0m" #<==34m表示蓝色字。
    echo -e "33[35m 洋红字oldboy trainning 33[0m" #<==35m表示洋红色字(magenta),和紫色字相近。
    echo -e "33[36m 蓝绿色oldboy trainning 33[0m" #<==36m表示蓝绿色字(cyan),和浅蓝色字相近。
    echo -e "33[37m 白色字oldboy trainning 33[0m" #<==37m表示白色字。
    

    基础脚本1:

    [root@centos6-kvm3 scripts]# cat 09-04.sh
    #!/bin/bash
    cat <<EOF
    1.apple
    2.pear
    3.banana
    4.cherry
    EOF
    read -p "请输入一个数字{1|2|3|4}:" num
    expr $num + 2 &>/dev/null
    if [ $? -ne 0 ]
    then
       echo "usage:$0 {1|2|3|4}"
       exit 1
    fi
    case $num in
       1)
       echo -e "33[31m apple 33[0m"
       ;;
       2)
       echo -e "33[32m pear 33[0m"
       ;;
       3)
       echo -e "33[33m banana 33[0m"
       ;;
       4)
       echo -e "33[34m cherry 33[0m"
       ;;
       *)
       echo "usage:$0 {1|2|3|4}"
       exit
    esac
    [root@centos6-kvm3 scripts]# 
    

    高级脚本2:

    颜色函数:
    [root@centos6-kvm3 scripts]# cat color.sh
    #!/bin/bash
    red="33[31m"
    green="33[32m"
    yellow="33[33m"
    blue="33[34m"
    tail="33[0m"
    color(){
    case $1 in
         red)
         echo -e "${red}$2${tail}"
         ;;
         green)
         echo -e "${green}$2${tail}"
         ;;
         yellow)
         echo -e "${yellow}$2${tail}"
         ;;
         blue)
         echo -e "${blue}$2${tail}"
         ;;
         *)
         echo "usage:$0 please input right content"
    esac
    
    }
    color $*
    [root@centos6-kvm3 scripts]# 
    功能调用颜色函数:
    [root@centos6-kvm3 scripts]# cat  09-04.sh 
    #!/bin/bash
    . ./color.sh
    cat <<EOF
    1.apple
    2.pear
    3.banana
    4.cherry
    EOF
    read -p "请输入一个数字{1|2|3|4}:" num
    expr $num + 2 &>/dev/null
    if [ $? -ne 0 ]
    then
       echo "usage:$0 {1|2|3|4}"
       exit 1
    fi
    case $num in
       1)
       color red apple
       ;;
       2)
       color green pear
       ;;
       3)
       color yellow banana
       ;;
       4)
       color blue cheryy
       ;;
       *)
       echo "usage:$0 {1|2|3|4}"
       exit
    esac
    [root@centos6-kvm3 scripts]# 
    
    
    字的背景颜色对应的数字范围为40-47,代码如下。
    echo -e "33[40;37m 黑底白字oldboy33[0m"   #<==40m表示黑色背景。
    echo -e "33[41;37m 红底白字oldboy33[0m"   #<==41m表示红色背景。
    echo -e "33[42;37m 绿底白字oldboy33[0m"   #<==42m表示绿色背景。
    echo -e "33[43;37m 棕底白字oldboy33[0m"   #<==43m表示棕色背景(brown),和黄色背景相近。
    echo -e "33[44;37m 蓝底白字oldboy33[0m"   #<==44m表示蓝色背景。
    echo -e "33[45;37m 洋红底白字oldboy33[0m"  #<==45m表示洋红色背景(magenta),和紫色背景相近。
    echo -e "33[46;37m蓝绿底白字oldboy33[0m"   #<==46m表示蓝绿色背景(cyan),和浅蓝色背景相近。
    echo -e "33[47;30m 白底黑字oldboy33[0m"    #<==47m表示白色背景。
    

    rsync启动基本脚本:

    [root@centos6-kvm3 scripts]# cat rsync.sh
    #!/bin/bash
    case $1 in
         start)
         rsync --daemon
         if [ $? -eq 0 ]
         then
            echo "rsync $1 ok"
         else
            echo "rsync $1 fail"
         fi
         ;;
         stop)
         killall rsync
         if [ $? -eq 0 ]
         then
            echo "rsync $1 ok"
         else
            echo "rsync $1 fail"
         fi
         ;;
         restart)
         killall rsync && sleep 1 && rsync --daemon
         if [ $? -eq 0 ]
         then
            echo "rsync $1 ok"
         else
            echo "rsync $1 fail"
         fi
         ;;
         *)
         echo "usage:$0 {start|stop|restart}"
    esac
    [root@centos6-kvm3 scripts]# 
    

    查看进程:lsof -i:873

    rsync启动高级脚本:

    cp rsyncd.sh /etc/init.d/rsyncd

    chkconfig --list rsyncd

    chkconfig --add rsyncd

    chmod +x /etc/init.d/rsyncd

    [root@centos6-kvm3 scripts]# cat rsyncd.sh 
    # chkconfig: 2345 20 80
    # description: rsync start stop
    
    #!/bin/bash
    . /etc/init.d/functions
    start(){
        rsync --daemon
        retval=$?
        if [ $retval -eq 0 ]
         then
            action  "rsync start ok" /bin/true
            return $retval
        else
            action "rsync start fail" /bin/false
            return $retval
        fi
    }
    stop(){
         killall rsync &>/dev/null
         retval=$?
         if [ $retval -eq 0 ]
         then
            action "rsync stop ok" /bin/true
            return $retval
         else
            action "rsync stop fail" /bin/false
            return $retval
         fi
    }
    case $1 in
         start)
         start
         retval=$?
         ;;
         stop)
         stop
         retval=$?
         ;;
         restart)
         stop 
         sleep 2
         start
         retval=$?
         ;;
         *)
         echo "usage:$0 {start|stop|restart}"
    esac
    exit $retval
    
    [root@centos6-kvm3 scripts]# 
    

    十、while循环

    (一)while循环语法

    while 循环语法
    while <条件表达式>
    do
      指令
    done
    

    (二)范例1:

    每隔2s输出系统负载情况。

    [root@centos6-kvm3 scripts]# cat 10-01.sh 
    #!/bin/bash
    while true
    do
     uptime >>/tmp/oldboy.log
     sleep 2
    done
    [root@centos6-kvm3 scripts]# 
    

    用法 说明
    sh while1.sh & 把脚本while1.sh放到后台执行(后台运行脚本时常用)*
    nohup while1.sh & 使用nohup 把脚本while.sh放到后台执行。
    ctl+c 停止执行当前脚本或者任务
    ctl+z 暂停执行当前脚本或者任务
    bg 把当前脚本或者任务放到后台执行,bg可以理解为backround
    fg 把当前脚本或者任务拿到前台执行,如果有多个任务,可以使用fg加任务编号调出对应脚本任务,如fg 2,调出第二个脚本任务,fg可以理解为frontground
    jobs 查看当前执行的脚本或者任务
    kill 关闭执行的脚本任务,即以“kill %任务编号”的形式关闭脚本,这个任务标号,可以通过jobs获得。

    后台运行 & ,nohup,screen(运维人员)

    常用命令:

    • kill,killall,pkill :杀掉进程
    • ps:查看进程。
    • pstree:显示进程状态树。
    • top:显示进程。
    • renice:改变优先权。
    • nohup:用户退出系统之后继续工作。
    • pgrep:查找匹配条件的进程。
    • strace:跟踪一个进程的系统调用情况。
    • ltrace:跟踪进程调用库函数的情况。

    (三)范例2:

    请使用while循环对下面的脚本进行修改,使得当执行脚本时,每次执行完脚本以后不退出脚本了,而是继续提示用户输入。

    [root@centos6-kvm3 scripts]# cat 10-02.sh
    #!/bin/bash
    while true
    do
    	read -t 15 -p "please input two number:" a b
            expr $a + $b + 2 &>/dev/null
            if [ $? -ne 0 ]
            then
               echo "usage:$0 please input two number."
               continue
            fi
            if [ -z "$b" ]
            then
               echo "usage:$0 please input two number."
               continue
            fi
    	echo "a-b=$(($a-$b))"
    	echo "a+b=$(($a+$b))"
    	echo "a*b=$(($a*$b))"
    	echo "a/b=$(($a/$b))"
    	echo "a**b=$(($a**$b))"
    	echo "a%b=$(($a%$b))"
    done
    [root@centos6-kvm3 scripts]# 
    

    (四)范例3:

    猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,如果不符合要求,就给予高或低的提示,猜对后则给出猜对用的次数,请用while语句实现。

    [root@centos6-kvm3 scripts]# cat 10-04.sh
    #!/bin/bash
    random=$((RANDOM%60))
    count=0
    while true
    do
      read -p "please input a num:" num
      ((count+=1))
      if [ $random -lt $num ]
      then
         echo "你猜大了"
      elif [ $random -gt $num ]
      then
         echo "你猜小了"
       else
         echo "你猜对了,NB!共计猜了${count}次!"
         exit 1
      fi
      
    done
    [root@centos6-kvm3 scripts]# 
    

    (五)范例4:

    分析Apache访问日志(access_2010-12-8.log),把日志中每行的访问字节数对应字段数字相加,计算出总的访问量。

    [root@centos6-kvm3 scripts]# cat 10-05.sh 
    #!/bin/bash
    sum=0
    awk '{print $10}' access_2010-12-8.log | grep -v - >./oldboy.log
    while read line
    do
      ((sum=sum+line))
    done <./oldboy.log
    echo $sum
    [root@centos6-kvm3 scripts]# sh 10-05.sh
    1380681
    

    十一、for循环语句应用实践

    (一)、for循环语法

    1)普通语法
    for 变量名 in 变量取值列表
    do
       指令。。。
    done
    2)c语言型for循环语法
    for(( exp1;exp2;exp3))
    do
       指令。。。
    done
    

    (一)范例1

    用for循环竖向打印1、2、3、4、5共5个数字。

    [root@centos6-kvm3 scripts]# cat 11-01.sh
    #!/bin/bash
    for n in {1..5}
    do
     echo $n
    done
    [root@centos6-kvm3 scripts]# sh 11-01.sh
    1
    2
    3
    4
    5
    [root@centos6-kvm3 scripts]# 
    

    (二)范例2:

    通过开发脚本实现仅设置sshd rsyslog crond network sysstat服务开机自启动。

    [root@centos6-kvm3 scripts]# cat 11-02.sh 
    #!/bin/bash
    for name in sshd rsyslog crond network sysstat
    do
     chkconfig $name on
    done
    [root@centos6-kvm3 scripts]# chkconfig --list | grep 3:on
    crond          	0:off	1:off	2:on	3:on	4:on	5:on	6:off
    network        	0:off	1:off	2:on	3:on	4:on	5:on	6:off
    rsyslog        	0:off	1:off	2:on	3:on	4:on	5:on	6:off
    sshd           	0:off	1:off	2:on	3:on	4:on	5:on	6:off
    sysstat        	0:off	1:on	2:on	3:on	4:on	5:on	6:off
    扩展:
    [root@centos6-kvm3 scripts]# chkconfig --list | grep 3:on |awk '{print "chkconfig", $1, "off"}' | bash
    

    (三)范例3:

    计算从1加到100之和。

    [root@centos6-kvm3 scripts]# cat 11-03.sh
    #!/bin/bash
    for n in {1..100}
    do
      ((sum=sum+$n))
    done
    echo $sum
    [root@centos6-kvm3 scripts]# sh 11-03.sh
    5050
    [root@centos6-kvm3 scripts]# 
    方法2:
    for ((i=1;i<=100;i++))
    do
      ((sum=sum+$i))
    done
    echo $sum
    

    (四)案例4:

    在Linux下批量修改文件名,将文件名中的“_finished”去掉。

    准备测试数据,如下。

    方法1:
    ls *.jpg | awk -F "_finished" '{print "mv",$0, $1$2}'|bash
    方法2:
    [root@centos6-kvm3 scripts]# cat 11-04.sh
    #!/bin/bash
    for file in `ls 11/*.jpg`
    do
      mv $file `echo ${file/_finished/}`
    done
    [root@centos6-kvm3 scripts]# 
    方法3:
    rename "_finished" "" *.jpg
    

    十二、循环控制及状态返回值应用实践

    本章将带着大家学习以下几个特殊的命令break(循环控制)、continue(循环控制)、exit(退出脚本)、return(退出函数)。

    (一)、break、continue、exit、return的区别和对比

    在上述命令中,break、continue在条件语句及循环语句(for、while、if等)中用于控制程序的走向,而exit则用于终止所有语句并退出当前脚本,除此之外,exit还可以返回上一次程序或命令的执行状态值给当前Shell;return类似exit,只不过return仅用于在函数内部返回函数执行的状态值。

    命令 说明
    break n 如果省略n表示跳出整个循环,n表示跳出循环的层数。
    continue n 如果省略n表示跳过本次循环,忽略本次循环的剩余代码,进入循环的下一次循环。n表示退到第n层继续循环。
    exit n 退出当前shell程序,n为上一次程序执行的状态返回值。n也可以省略,再下一个shell里可通过$?接收exit n的n值。
    return n 用于在函数里,作为函数的返回值,用于判断函数执行是否正确。再下一个shell里可通过$?接收exit n的n值。

    十三、Shell数组应用实践

    (一)数组介绍

    为什么会产生数组

    通常在开发Shell脚本时,我们定义变量采用的形式为a=1;b=2;c=3,可如果有多个变量呢?这时再一个一个定义很费劲,并且要是有多个不确定的变量内容,也难以进行变量定义,此外,快速读取不同变量的值也是一件很痛苦的事情,于是数组就诞生了,它就是为了解决上述问题而来的。

    什么是Shell数组

    如果读者有过其他语言的编程经历,那么想必会熟悉数组的概念。简单地说,Shell的数组就是把有限个元素(变量或字符内容)用一个名字命名,然后用编号对它们进行区分的元素集合。这个名字就称为数组名,用于区分不同内容的编号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。

    有了Shell数组后,就可以用相同名字引用一系列变量及变量值,并通过数字(索引)来识别使用它们。在许多场合,使用数组可以缩短和简化程序开发。

    (二)数组的定义

    方法1:推荐
    array=(one two three four)
    方法2:
    array=([0]=one [1]=two [2]=three [3]=four)
    方法3:
    [root@web01 ~]# array[0]=one
    [root@web01 ~]# array[1]=two
    [root@web01 ~]# array[2]=three
    [root@web01 ~]# array[3]=four
    [root@web01 ~]# echo ${array[@]}
    one two three four
    方法4:命令的结果放到数组里,推荐。
    array=(`ls /server/scripts`)
    

    (三)、操作数组元素

    读取数组内容:*****
    [root@web01 ~]# array=( 1 2 3 4 5)
    [root@web01 ~]# echo ${array[0]}
    1
    [root@web01 ~]# echo ${array[1]}
    2
    [root@web01 ~]# echo ${array[2]}
    3
    [root@web01 ~]# echo ${array[3]}
    4
    [root@web01 ~]# echo ${array[4]}
    5
    [root@web01 ~]# echo ${array[5]}
    
    [root@web01 ~]# echo ${array[*]}
    1 2 3 4 5
    [root@web01 ~]# echo ${array[@]}
    1 2 3 4 5
    [root@web01 ~]# echo ${#array[@]}
    5
    [root@web01 ~]# echo ${#array[*]}
    5
    给数组增加内容:
    [root@web01 ~]# array[5]=oldboy
    [root@web01 ~]# echo ${#array[*]}
    6
    [root@web01 ~]# echo ${array[*]}
    1 2 3 4 5 oldboy
    
    删除数组元素:
    [root@web01 ~]# unset array[1]
    [root@web01 ~]# echo ${array[*]}
    1 3 4 oldboy
    [root@web01 ~]# unset array[0]
    [root@web01 ~]# echo ${array[*]}
    3 4 oldboy
    数组能不能替换:
    使用for循环打印数组元素
    array=(1 2 3 4 5)
    for n in ${array[*]}
    do
        echo $n
    done
    echo =====================
    #i为数组下标
    for ((i=0;i<${#array[*]};i++))
    do
        echo ${array[i]}
    done 
    array=([1]=one [2]=two [3]=three) 
    array[0]=a;array[1]=b;array[2]=c
    array=($(命令))
    或
    array=(`命令`)
  • 相关阅读:
    android intent 隐式意图和显示意图(activity跳转)
    Stack栈的三种含义
    gdi+ 高速绘制透明窗体
    Hibernate Criterion
    iOS安全攻防(三):使用Reveal分析他人app
    Android入门第八篇之GridView(九宫图)
    【Android动画】之Tween动画 (渐变、缩放、位移、旋转)
    Ubuntu下deb包的安装方法
    理解class.forName()
    Myeclipse7.5 下载 安装 注冊 注冊码 100%成功
  • 原文地址:https://www.cnblogs.com/cuiyongchao007/p/12239425.html
Copyright © 2020-2023  润新知