SHELL中的循环:

循环: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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容