美文网首页初见
SHELL中的循环:

SHELL中的循环:

作者: 汤姆森森 | 来源:发表于2019-10-11 23:31 被阅读0次

    循环:for, while, until

            循环体:要执行的代码;可能要执行n遍;

                进入条件:

                退出条件:

            for循环:

                for 变量名  in 列表; do

                    循环体

                done

                执行机制:

                    依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束;

                示例:添加10个用户, user1-user10;密码同用户名;

                    #!/bin/bash

                    #

                    if [ ! $UID -eq 0 ]; then

                        echo "Only root."

                        exit 1

                    fi

                    for i in {1..10}; do

                        if id user$i &> /dev/null; then

                          echo "user$i exists."

                        else

                            useradd user$i

                        if [ $? -eq 0 ]; then

                            echo "user$i" | passwd --stdin user$i &> /dev/null

                                echo "Add user$i finished."

                            fi

                        fi

                    done

                列表生成方式:

                    (1) 直接给出列表;

                    (2) 整数列表:

                        (a) {start..end}

                        (b) $(seq [start [step]] end)

                    (3) 返回列表的命令;

                        $(COMMAND)

                    (4) glob

                    (b) 变量引用;

                        $@, $*

                示例:判断某路径下所有文件的类型

                    #!/bin/bash

                    #

                    for file in $(ls /var); do

                        if [ -f /var/$file ]; then

                        echo "Common file."

                        elif [ -L /var/$file ]; then

                        echo "Symbolic file."

                        elif [ -d /var/$file ]; then

                        echo "Directory."

                        else

                        echo "Other type."

                        fi

                    done           

                示例:

                    #!/bin/bash

                    #

                    declare -i estab=0

                    declare -i listen=0

                    declare -i other=0

                    for state in $( netstat -tan | grep "^tcp\>" | awk '{print $NF}'); do

                        if [ "$state" == 'ESTABLISHED' ]; then

                        let estab++

                        elif [ "$state" == 'LISTEN' ]; then

                        let listen++

                        else

                        let other++

                        fi

                    done

                    echo "ESTABLISHED: $estab"

                    echo "LISTEN: $listen"

                    echo "Unkown: $other"               

        练习1:/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;

            分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;

                “K34filename stop”

                “S66filename start”

        练习2:写一个脚本,使用ping命令探测172.16.250.1-254之间的主机的在线状态;

    for循环语法:

            for NAME in LIST; do

                循环体

            done

            列表生成方式:

                (1) 整数列表

                    {start..end}

                    $(seq start [[step]end])

                (2) glob

                    /etc/rc.d/rc3.d/K*

                (3) 命令

            通过ping命令探测10.49.128.1-254范围内的所有主机的在线状态;

                #!/bin/bash

                #

                net='10.49.128'

                uphosts=0

                downhosts=0

                for i in {1..20}; do

                    ping -c 1 -w 1 ${net}.${i} &> /dev/null

                    if [ $? -eq 0 ]; then

                    echo "${net}.${i} is up."

                        let uphosts++

                    else

                    echo "${net}.${i} is down."

                        let downhosts++

                    fi

                done

                   

                echo "Up hosts: $uphosts."

                echo "Down hosts: $downhosts."           

        while循环:

            while CONDITION; do

                循环体

                循环控制变量修正表达式

            done

            进入条件:CONDTION测试为"真"

            退出条件:CONDTION测试为"假"

                因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正;

        until循环:

            until CONDITION; do

                循环体

                循环控制变量修正表达式

            done

            进入条件:CONDTION测试为"假"

            退出条件:CONDTION测试为"真"

           

            示例:求100以内所有正整数之和;

                #!/bin/bash

                #

                declare -i sum=0

                declare -i i=1

                while [ $i -le 100 ]; do

                    let sum+=$i

                    let i++

                done

                echo "$i"

                echo "Summary: $sum."

            练习:添加10个用户

                user1-user10

                #!/bin/bash

                #

                declare -i i=1

                declare -i users=0

                while [ $i -le 10 ]; do

                    if ! id user$i &> /dev/null; then

                    useradd user$i

                      echo "Add user: user$i."

                        let users++

                    fi

                    let i++

                done

                echo "Add $users users."           

            练习:通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态;(用while循环)

                #!/bin/bash

                #

                declare -i i=1

                declare -i uphosts=0

                declare -i downhosts=0

                net='172.16.250'

                while [ $i -le 20 ]; do

                    if ping -c 1 -w 1 $net.$i &> /dev/null; then

                        echo "$net.$i is up."

                        let uphosts++

                    else

                        echo "$net.$i is down."

                        let downhosts++

                    fi

                    let i++

                done

                echo "Up hosts: $uphosts."

                echo "Down hosts: $downhosts."

            练习:打印九九乘法表;(分别使用for和while循环实现)

                #!/bin/bash

                #

                for j in {1..9}; do

                    for i in $(seq 1 $j); do

                        echo -e -n "${i}X${j}=$[$i*$j]\t"

                    done

                    echo

                done           

                #!/bin/bash

                #

                declare -i i=1

                declare -i j=1

                while [ $j -le 9 ]; do

                    while [ $i -le $j ]; do

                        echo -e -n "${i}X${j}=$[$i*$j]\t"

                        let i++

                    done

                    echo

                    let i=1

                    let j++

                done

            练习:利用RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者;

                #!/bin/bash

                #

                declare -i max=0

                declare -i min=0

                declare -i i=1

                while [ $i -le 9 ]; do

                    rand=$RANDOM

                    echo $rand

                    if [ $i -eq 1 ]; then

                        max=$rand

                        min=$rand

                    fi

                    if [ $rand -gt $max ]; then

                        max=$rand

                    fi

                    if [ $rand -lt $min ]; then

                        min=$rand

                    fi

                    let i++

                done

                echo "MAX: $max."

                echo "MIN: $min."

    bash脚本编程

        while CONDITION; do

            循环体

        done

        进入条件:CONDITION为true;

        退出条件:false

        until CONDITION; do

            循环体

        done

        进入条件:false

        退出条件:true

            示例:求100以内所正整数之和;

                #!/bin/bash

                #

                declare -i i=1

                declare -i sum=0

                until [ $i -gt 100 ]; do

                    let sum+=$i

                    let i++

                done

                echo "Sum: $sum"   

            示例:打印九九乘法表

                #!/bin/bash

                #

                declare -i j=1

                declare -i i=1

                until [ $j -gt 9 ]; do

                    until [ $i -gt $j ]; do

                        echo -n -e "${i}X${j}=$[$i*$j]\t"

                        let i++

                    done

                    echo

                    let i=1

                    let j++

                done

        循环控制语句(用于循环体中):

            continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;

                while CONDTIITON1; do

                    CMD1

                    ...

                    if CONDITION2; then

                        continue

                    fi

                    CMDn

                    ...

                done

            break [N]:提前结束循环;                   

                while CONDTIITON1; do

                    CMD1

                    ...

                    if CONDITION2; then

                        break

                    fi

                    CMDn

                    ...

                done

            示例1:求100以内所有偶数之和;要求循环遍历100以内的所正整数;

                #!/bin/bash

                #

                declare -i i=0

                declare -i sum=0

                until [ $i -gt 100 ]; do

                    let i++

                    if [ $[$i%2] -eq 1 ]; then

                        continue

                    fi

                    let sum+=$i

                done

                echo "Even sum: $sum"

        创建死循环:

            while true; do

                循环体

            done

            until false; do

                循环体

            done

            示例2:每隔3秒钟到系统上获取已经登录的用户的信息;如果docker登录了,则记录于日志中,并退出;

                #!/bin/bash

                #

                read -p "Enter a user name: " username

                while true; do

                    if who | grep "^$username" &> /dev/null; then

                        break

                    fi

                    sleep 3

                done

                echo "$username logged on." >> /tmp/user.log                   

                第二种实现:

                #!/bin/bash

                #

                read -p "Enter a user name: " username

                until who | grep "^$username" &> /dev/null; do

                    sleep 3

                done

                echo "$username logged on." >> /tmp/user.log

        while循环的特殊用法(遍历文件的每一行):

            while read line; do

                循环体

            done < /PATH/FROM/SOMEFILE

            依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line:

            示例:找出其ID号为偶数的所有用户,显示其用户名及ID号;

                #!/bin/bash

                while read line;do

                        if [ $[`echo $line | cut -d: -f3` % 2] -eq 0 ];then

                                echo -e -n "username: `echo $line | cut -d: -f1`\t"

                                echo "uid: `echo $line | cut -d: -f3 `"

                        fi

                done < /etc/passwd       

        for循环的特殊格式:

            for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)); do

                循环体

            done

            控制变量初始化:仅在运行到循环代码段时执行一次;

            控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断;

            示例:求100以内所正整数之和;

                #!/bin/bash

                #

                declare -i sum=0

                for ((i=1;i<=100;i++)); do

                    let sum+=$i

                done

                echo "Sum: $sum."

            示例2:打印九九乘法表;

                #!/bin/bash

                #

                for((j=1;j<=9;j++));do

                        for((i=1;i<=j;i++))do

                            echo -e -n "${i}X${j}=$[$i*$j]\t"

                        done

                        echo

                done

    相关文章

      网友评论

        本文标题:SHELL中的循环:

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