• Shell编程中while与for的区别及用法详解【转】


    在shell编程中经常用到循环,常用的循环有for和while循环两种。while循环默认以行读取文件,而for循环以空格读取文件切分文件,本篇就结合现网的一些使用示例说说二者的用法和区别。

    一、常用语法

    1、for循环

    for循环常用的语法结构有如下几种:

    for 变量 in seq字符串
    for 变量 in `command` " "
    for 变量 in "$@"或“$*”
    for((赋值;条件;运算语句))

    2、while循环

    while循环常用的语法结构有如下几种:

    1
    2
    3
    4
    while [ $i -lt num ]
    while true
    while read a b c; do command done < filename
    cat filename | while read a b c

    二、行读取示例

    这里以常见的df获取磁盘信息为例,了解下使用for和while的几种循环方法处理时的区别。先看下我写的脚本,内容如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #/bin/bash
    ## author: yangbk
    ## site: www.361way.com
    ## mail: itybku@139.com
    ## desc: test loop for in and while
    df -hl|awk 'int($5) >30 ' > testfile
    result=`df -hl|awk 'int($5) >30 '`
    echo '******************* for testing *****************'
    for i in $result;do
    echo $i
    done
    echo '******************* while echo test *************'
    echo $result | while read line
    do
    echo $line
    done
    echo '****************** while testing ****************'
    df -hl|awk 'int($5) >30 '|while read line
    do
    echo $IP `hostname` $line
    done
    echo '****************** while read file **************'
    while read line
    do
    echo $IP `hostname` $line
    done < testfile

    上面的脚本执行时结果如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    # sh forwhile.sh
    ******************* for testing *****************
    /dev/sda3
    9.5G
    5.7G
    3.4G
    64%
    /
    /dev/sda2
    39G
    19G
    18G
    52%
    /home
    /dev/sda6
    9.5G
    7.1G
    2.0G
    78%
    /usr
    ******************* while echo test *************
    /dev/sda3 9.5G 5.7G 3.4G 64% / /dev/sda2 39G 19G 18G 52% /home /dev/sda6 9.5G 7.1G 2.0G 78% /usr
    ****************** while testing ****************
    localhost /dev/sda3 9.5G 5.7G 3.4G 64% /
    localhost /dev/sda2 39G 19G 18G 52% /home
    localhost /dev/sda6 9.5G 7.1G 2.0G 78% /usr
    ****************** while read file **************
    localhost /dev/sda3 9.5G 5.7G 3.4G 64% /
    localhost /dev/sda2 39G 19G 18G 52% /home
    localhost /dev/sda6 9.5G 7.1G 2.0G 78% /usr

    可以看到,只有后面两种方法可以正常获取到我们想要的数据,前面两种方法在处理时和我们想要的结果都不一样。此示例得出的结果为:

    1、while循环: 以行读取文件,默认分隔符是空格或者Tab;

    2、for循环: 以空格读取文件,也就是碰到空格,就开始执行循环体,所以需要以行读取的话,就要把空格转换成其他字符。

    三、ssh连接与wait

    这里还是以一个测试脚本为例:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #!/bin/bash
    ## author: yangbk
    ## site: www.361way.com
    ## mail: itybku@139.com
    ## desc: test wait and ssh when use for in and while
    # while loop
    echo -en " ";date
    cat abc.txt|while read user ip
    do
    {
    ssh -o ConnectTimeout=10 $user@$ip "hostname" < /dev/null
    sleep 10s
    } &
    done
    wait
    echo "This is while loop."
    echo -en " ";date
    sleep 10s
    echo -e " "
    # for loop
    echo -en " ";date
    for line in `cat abc.txt|sed -e 's/ /--/g'`
    do
    {
    user=`echo $line|awk -F '--' '{print $1}'`
    ip=`echo $line|awk -F '--' '{print $2}'`
    ssh -oConnectTimeout=10 $user@$ip "hostname"
    sleep 10s
    } &
    done
    wait
    echo "This is for loop."
    echo -en " ";date

    此示例的结果这里不再输出,具体可以使用该脚本ssh几台主机做个测试,测试后得到结果如下:

    1、for循环: 循环体在后台执行,等待循环体全部执行结束,后面的命令接着执行。

    2、while循环: wait没起到作用,循环体在后台执行,后面的命令也同时在执行。循环体内有ssh、scp、sshpass的时候有执行一次循环就退出的情况,解决该问题方法有如下两种:

    a、使用ssh -n "command" ;
    b、将while循环内加入null重定向,如 ssh "cmd" < /dev/null 将ssh 的输入重定向输入。

    四、执行效率

    在对大文件进行按行读取(for在读取文件时,可以for i in `cat filename`进行按行读取)的效率方面,经测试while 要更快一些。

    shell:for和while用法

    写法一:

    ----------------------------------------------------------------------------
    #!/bin/bash

    while read line
    do
    echo $line
    done < file(待读取的文件)
    ----------------------------------------------------------------------------

    写法二:(并发脚本慎用,grep不能输出全部匹配的信息)
    ----------------------------------------------------------------------------
    #!/bin/bash

    cat file(待读取的文件) | while read line
    do
    echo $line
    done
    ----------------------------------------------------------------------------

    写法三:

    ----------------------------------------------------------------------------
    for line in `cat file(待读取的文件)`
    do
    echo $line
    done
    ----------------------------------------------------------------------------

    说明:

    for逐行读和while逐行读是有区别的,如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    $ cat file
    aaaa
    bbbb fff ggg
    cccc dddd
    $ cat file | while read line; do echo $line; done
    aaaa
    bbbb fff ggg
    cccc dddd
    $ for line in $(<file); do echo $line; done
    aaaa
    bbbb
    fff
    ggg
    cccc
    dddd
  • 相关阅读:
    pip解决超时问题(timeout)
    Docker commit使用
    Docker基本命令汇总
    python redis模块详解
    python异步编程之asyncio(百万并发)
    VideoJS 与 Framework7 中 fastclick 冲突问题
    Linux 下解决安装多个node冲突的问题(重新安装node)
    git push multiple repo
    webpack import windows case sensitive
    一键切图 PS 动作 【收藏】
  • 原文地址:https://www.cnblogs.com/paul8339/p/9619833.html
Copyright © 2020-2023  润新知