• shell编程下


    第1章 Whicle

    1.1 while循环语句

    在编程语言中,while循环(英语:while loop)是一种控制流程的陈述。利用一个返回结果为布林值(Boolean)的表达式作为循环条件,当这个表达式的返回值为“真”(true)时,则反复执行循环体内的程式码;若表达式的返回值为“假”(false),则不再执行循环体内的代码,继续执行循环体下面的代码。

             因为while循环在区块内代码被执行之前,先检查陈述是否成立,因此这种控制流程通常被称为是一种前测试循环(pre-test loop)。相对而言do while循环,是在循环区块执行结束之后,再去检查陈述是否成立,被称为是后测试循环。

    1.2 shell中while语法

    while 条件

      do

        命令

    done

    1.3 while的使用场景

    多用于创建守护进程

    while实现web服务器搭建

    脚本代码

    while创建定时任务

    #!/bin/bash

    while  true

      do

        uptime

           sleep 0.6

    done

    说明:

             sleep 与 usleep

    sleep 单位 秒  sleep 1 休息1

    usleep 单位 微秒 usleep 1000000 休息1s

    1微秒等于百万分之一秒(10的负6次方秒)

    1.4 while作用

      补充定时任务功能,执行小于1秒的定时任务

      循环执行某些操作,例如水果菜单

    1.5  例题

    这苹果多少钱一斤啊?

          请猜0-60的数字

    请输入你的价格:30

    嘿嘿,要不你用这个价买?

    再给你一次机会,请继续猜:

    请输入你的价格:26

    太低太低

    再给你一次机会,请继续猜:

    请输入你的价格:27

    猜对了,就是27元

    一共猜了3次,太牛了。

    !/bin/bash

    a=$((RANDOM%60))

    while true

    do

        read -p "请输入一个价格" b

        if [ $b -gt $a ]

        then

            echo "猜大了,请继续"

        elif [ $b -eq $a ]

        then

            echo "恭喜猜对了"

        else

            echo "猜小了,请继续"

        fi

    done                  

    完善

    1.6 获取文件中的每一行

    方式1:采用exec读取文件后,然后进入while循环处理。
    exec <FILE
    sum=0
    while read line
    do
        cmd
    done
    方式2:使用cat读取文件内容,然后通过管道进入while循环处理。
    cat FILE_PATH|while read line
    do
        cmd
    done
    方式3:在while循环结尾done通过输入重定向指定读取的文件。
    while read line
    do
        cmd
    done<FILE

    第2章 Shell中的数组

    2.1 为什么会产生Shell数组

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

    2.2 什么是shell数组

    Shell的数组就是一个元素集合,它把有限个元素(变量或字符内容)用一个名字来 命名,然后用编号对它们进行区分。这个名字就称为数组名,用于区分不同内容的编 号就称为数组下标。组成数组的各个元素(变量)称为数组的元素,有时也称为下标变量。

    2.3 数组中的简单规则

    [root@db03 scripts]# array=(1 2 3)

    查看第一个数字

     [root@db03 scripts]# echo ${array[0]}

    1

    查看第3字

    [root@db03 scripts]# echo ${array[2]}

    3

    查看所有的数字

    [root@db03 scripts]# echo ${array[*]}

    1 2 3

    [root@db03 scripts]# echo ${array[@]}

    1 2 3

    查看所有数字个数

    [root@db03 scripts]# echo ${#array[@]}

    3

    2.4 数组定义的方法

    array=(1 2 3) 推荐

    array=([1]=one [2]=two [3]=three)

    array[0]=a;array[1]=b;array[2]=c

    array=(`命令`)

    array=($(命令)) 推荐

    2.5 两种显示的方法

    array=(1 2 3 4 5)
    for n in ${array[*]}
    do
        echo $n
    done

    for ((i=0;i<${#array[*]};i++))
    do
        echo ${array[i]}
    done

    2.6 例题:利用bash for循环打印下面这句话中字母数不大于6

    的单词(某企业面试真题)。

    I am oldboy teacher welcome to oldboy training class

    2.7 把/server/scripts下的所有文件放到数组里,然后再输出!

    最后把结尾为.sh的文件改为.log。

    rename .log .sh *.log

    第3章 脚本运行的用法和说明

    第4章 break continue 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值

    简单来说即:
    break    跳出循环

    continue 跳出本次循环

    exit     退出脚本

    return   与 exit 相同,在函数中使用

    4.1 break说明

    [root@clsn scripts]# help break

    break: break [n]

        退出 for、while、或 until 循环

       

        退出一个 FOR、WHILE 或 UNTIL 循环。如果指定了N,则打破N重

        循环

       

        退出状态:

        退出状态为0除非 N 不大于或等于 1。

      测试脚本内容

     1 #!/bin/bash

     2

     3 for i in {1..5}

     4

     5   do

     6

     7     if [ $i -eq 3 ]

     8

     9       then

    10

    11        break

    12

    13     fi

    14

    15     echo $i

    16

    17 done

    18

    19 echo "ok"

    View Code break 测试脚本

      脚本执行结果

    [root@clsn scripts]# sh break.sh

        1

        2

        ok

    4.2  continue命令说明

    [root@clsn scripts]# help continue

    continue: continue [n]

        继续 for、while、或 until 循环。

       

        继续当前 FOR、WHILE 或 UNTIL 循环的下一步。

        如果指定了 N, 则继续当前的第 N 重循环。

       

        退出状态:

        退出状态为 0 除非 N 不大于或等于1。

      测试脚本内容

    1 #!/bin/bash

     2     for i in {1..5}

     3       do

     4         if [ $i -eq 3 ]

     5           then

     6             continue

     7         fi

     8         echo $i

     9     done

    10     echo "ok"

    View Code continue 测试脚本

      脚本执行结果

    [root@clsn scripts]# sh continue.sh

    1

    2

    4

    5

    ok

    4.3  exit命令说明

    [root@clsn scripts]# help exit

    exit: exit [n]

        退出shell。

       

        以状态 N 退出 shell。  如果 N 被省略,则退出状态

        为最后一个执行的命令的退出状态。

      测试脚本内容

     1     #!/bin/bash

     2     for i in {1..5}

     3       do

     4         if [ $i -eq 3 ]

     5           then

     6             exit

     7         fi

     8         echo $i

     9     done

    10     echo "ok"

    View Code exit 测试脚本

      脚本执行结果

        [root@clsn scripts]# sh exit.sh

        1

        2

    4.4 return命令说明

    [root@clsn tuichu]# help return

    return: return [n]

        从一个 shell 函数返回。

       

        使一个函数或者被引用的脚本以指定的返回值 N 退出。

        如果 N 被省略,则返回状态就是

        函数或脚本中的最后一个执行的命令的状态。

       

        退出状态:

        返回 N,或者如果 shell 不在执行一个函数或引用脚本时,失败。

    第5章 题海

    5.1 使用for循环在/oldboy目录下通过随机小写10个字母加固定字符串oldboy批量创建10个html文件,名称例如为:path=/oldboy

    [ ! -d $path ] && mkdir $path -p

    cd $path

    for n in {1..10}

    do

        random=`echo $RANDOM$(date +%N)|md5sum|tr "[0-9]" "a-z"|cut -c 2-11`

        touch ${random}_oldboy.html

    done

    5.2 将以上文件名中的oldboy全部改成oldgirl(用for循环实现),并且html改成大写

    path=/oldboy
    [ ! -d $path ] && mkdir $path -p
    cd $path
    for file in `ls *oldboy.html`
    do
         mv $file ${file/oldboy.html/oldgirl.HTML}
    done

    5.3 批量创建用户并设置 随机密码

    . /etc/init.d/functions
    for i in {11..15}
    do
        password=$(echo $RANDOM|md5sum|cut -c 1-8)
        useradd oldboy$i &>/dev/null &&
        echo $password|passwd --stdin oldboy$i &>/dev/null &&
        echo -e "oldboy$i  $password" >>/tmp/userlist.txt
        if [ $? -eq 0 ]
        then
            action "userad oldboy$i is ok" /bin/true
        else
            action "userad oldboy$i is fail" /bin/false
        fi
    done

    5.4 查看10.0.0.0、24 网段的那个网址正确

    5.5 Mysql启动脚本

    . /etc/init.d/functions

     

    basedir=/application/mysql

    bindir=/application/mysql/bin

    lockdir='/var/lock/subsys'                                      

    lock_file_path="$lockdir/mysql"

    mysqld_pid_file_path=$basedir/data/db03.pid

     

    log_success_msg(){

        action "SUCCESS! $@" /bin/true

    }

     

    log_failure_msg(){

        action  "ERROR! $@" /bin/false

      }

     

    start(){

        echo $"Starting MySQL"

        if test -x $bindir/mysqld_safe

        then

            $bindir/mysqld_safe &>/dev/null &

            return_value=$?

            if [ $return_value -eq 0 ]

            then

                log_success_msg "mysql Startup"

                if test -w "$lockdir"

                then

                    touch "$lock_file_path"

                fi

                return $return_value

            else

                log_failure_msg "MySQL Startup"

                return $return_value

            fi

        else

            log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"

        fi

    }

    stop(){

        if test -s "$mysqld_pid_file_path"

        then

            mysqld_pid=`cat "$mysqld_pid_file_path"`

            if (kill -0 $mysqld_pid 2>/dev/null)

            then

                echo $"Shutting down MySQL"

                kill $mysqld_pid

                return_value=$?

                if [ $return_value -eq 0 ]

                then

                    log_success_msg "mysql Stop"

                    if test -f "$lock_file_path"

                    then

                        rm -f "$lock_file_path"

                    fi

                    return $return_value

                else

                    log_failure_msg "MySQL Stop."

                    return $return_value

                fi

            else

                log_failure_msg "MySQL server process #$mysqld_pid is not running!"

                rm "$mysqld_pid_file_path"

            fi 

        else

            log_failure_msg "MySQL server PID file is null or not exist!"

        fi

    }

     

    case "$1" in

        start)

            start

            return_value=$?

            ;;

        stop)

            stop

            return_value=$?

            ;;

        restart)

            $0 stop

            sleep 2

            $0 start

            return_value=$?

            ;;

        *)

            echo $"Usage:$0 {start|stop|restart}"

    esac

    exit $return_value

    5.6 破解密码

    已知下面的字符串是通过RANDOM随机数变量md5sum|cut-c 1-8截取后的结果,请破解这些字符串对应的md5sum前的RANDOM对应数字?

    21029299

    00205d1c

    a3da1677

    1f6d12dd

    890684b

    aaa=(

    21029299

    00205d1c

    a3da1677

    1f6d12dd

    890684b

    )

    a=/tmp/1.txt

    touch $a

    for b in `seq 32767`

    do

            c=$(echo $b|md5sum)                                          

            echo "$c $b"  >>$a

    done

    for  n  in ${aaa[*]}

    do

        egrep  "$n"  $a

    done

    5.7 批量检查多个网站地址是否正常 

    要求:shell数组方法实现,检测策略尽量模拟用户访问思路

    a=(

    http://www.etiantian.org

    http://www.taobao.com

    http://oldboy.blog.51cto.com

    http://10.0.0.7

    )

    for n in ${a[*]}

    do

        wget  -T 3 -t 2 $n &>/dev/null

        if [ $? -eq 0 ];then

            echo -e  "$n ok"

        else

            echo -e  "$n normal"                                         

        fi

    done

     

     

     

    . /etc/init.d/functions

    array=(
    http://www.etiantian.org
    http://www.taobao.com
    http://oldboy.blog.51cto.com
    http://10.0.0.7
    )

    checkUrl(){
         wget -T 5 -t 2 --spider -q $1 &>/dev/null
         if [ $? -eq 0 ]
         then
             action "$1 is ok" /bin/true
         else
             action "$1 is fail" /bin/false
         fi
    }

    rotateCheck(){
        for url in ${array[*]}
        do
            checkUrl $url
        done
    }

    main(){
        while true
        do
            rotateCheck
            echo "======================"
            echo "sleep 10"
            sleep 10
        done
    }
    main

    5.8 写一个Shell脚本解决DOS***生产案例。

    请根据web日志或者或者网络连接数,监控当某个IP并发连接数或者短时内PV达到100(读者根据实际情况设定),即调用防火墙命令封掉对应的IP。防火墙命令为:iptables-I INPUT -s IP地址 -j DROP。

    解答:

    ##############################################################

    log="access.log"

    while true

    do

        awk '{S[$1]++}END{for(k in S) print S[k],k}' $log|sort -rn|head

        |while read line

        do

            ip=`echo $line|awk '{print $2}'`

            count=`echo $line|awk '{print $1}'`

            if [ $count -lt 1000 ] || `grep "$ip" /tmp/beifeng.log &>/dev/null`

            then

                :

            else

                iptables -I INPUT -s $ip -j DROP &&

                    echo "$ip $(date +%F)" >>/tmp/beifeng.log

            fi

        done

        sleep 180

    done

  • 相关阅读:
    php自定义函数call_user_func和call_user_func_array详解
    微信开发(一) 服务器配置
    6487. 【GDOI2020模拟02.29】列强争霸war
    关于循环顺序对时间影响的一点研究
    6486. 【GDOI2020模拟02.25】向日葵人生
    6485. 【GDOI2020模拟02.25】沙塔斯月光
    6478. 【GDOI2020模拟02.19】C(上下界费用流、费用流消负环)
    6461. 【GDOI2020模拟02.05】生成树(矩阵树及其扩展、二维拉格朗日插值)
    上下界网络流&费用流
    6467. 【GDOI2020模拟02.09】西行寺无余涅槃(FWT的性质)
  • 原文地址:https://www.cnblogs.com/zdqc/p/9717106.html
Copyright © 2020-2023  润新知