linux 命令详解 二十七

    4.  循环语句:
    Bash Shell
中主要提供了三种循环方式:forwhileuntil
    for循环声明格式:
    for variable in word_list
    do
        command
    done
    
见如下示例脚本:
    /> cat > test7.sh
    for score in math english physics chemist   #for将循环读取in后面的单词列表,类似于Javafor-each
    do
        echo "score = $score"
    done
    echo "out of for loop"
    CTRL+D
    /> . ./test7.sh
    score = math
    score = english
    score = physics
    score = chemist
    out of for loop

    /> cat > mylist   #构造数据文件
    tom
    patty
    ann
    jake
    CTRL+D
    /> cat > test8.sh
    #!/bin/sh
    for person in $(cat mylist)                 #for将循环读取cat mylist命令的执行结果。
    do
        echo "person = $person"
    done
    echo "out of for loop."
    CTRL+D
    /> . ./test8.sh
    person = tom
    person = patty
    person = ann
    person = jake
    out of for loop.

    /> cat > test9.sh
    for file in test[1-8].sh                        #for将读取test1-test8,后缀为.sh的文件
    do
        if [ -f $file ]                              #判断文件在当前目录是否存在。
        then
            echo "$file exists."
        fi
    done
    CTRL+D
    /> . ./test9.sh
    test2.sh exists.
    test3.sh exists.
    test4.sh exists.
    test5.sh exists.
    test6.sh exists.
    test7.sh exists.
    test8.sh exists.

    /> cat > test10.sh
    for name in $*                                  #读取脚本的命令行参数数组,还可以写成for name的简化形式。
    do
        echo "Hi, $name"
    done
    CTRL+D
    /> . ./test10.sh stephen ann
    Hi, stephen
    Hi, ann

    while循环声明格式:
    while command  #如果command命令的执行结果为0,或条件判断为真时,执行循环体内的命令。
    do
        command
    done
    
见如下示例脚本:
    /> cat > test1.sh  
    num=0
    while (( num < 10 ))               #等同于 [ $num -lt 10 ]
    do
        echo -n "$num "
        let num+=1
    done
    echo -e "\nHere's out of loop."
    CTRL+D
    /> . ./test1.sh
    0 1 2 3 4 5 6 7 8 9
 
    Here's out of loop.

    /> cat > test2.sh
    go=start
    echo Type q to quit.
    while [[ -n $go ]]                     #等同于[ -n "$go" ],如使用该风格,$go需要被双引号括起。
    do
        echo -n How are you.
        read word
        if [[ $word == [Qq] ]]      #等同于[ "$word" = Q -o "$word" = q ]
        then
            echo Bye.
            go=                        #go变量的值置空。
        fi
    done
    CTRL+D
    /> . ./test2.sh
    How are you.
 Hi
    How are you.
 q
    Bye.

    until循环声明格式:
    until command                         #其判断条件和while正好相反,即command返回非0,或条件为假时执行循环体内的命令。
    do
        command
    done
    
见如下示例脚本:
    /> cat > test3.sh
    until who | grep stephen           #循环体内的命令将被执行,直到stephen登录,即grep命令的返回值为0时才退出循环。
    do
        sleep 1
        echo "Stephen still doesn't login."
    done
    CTRL+D

    shift命令声明格式:shift [n]
    shift
命令用来把脚本的位置参数列表向左移动指定的位数(n),如果shift没有参数,则将参数列表向左移动一位。一旦移位发生,被移出列表的参数就被永远删除了。通常在while循环中,shift用来读取列表中的参数变量。
    
见如下示例脚本:
    /> set stephen ann sheryl mark #设置4个参数变量。
    /> shift                                    #向左移动参数列表一次,将stephen移出参数列表。
    /> echo $*
    ann sheryl mark
    /> shift 2                                 #继续向左移动两位,将sherylann移出参数列表
    /> echo $*
    mark
    /> shift 2                                 #继续向左移动两位,由于参数列表中只有mark了,因此本次移动失败。
    /> echo $*
    mark

    /> cat > test4.sh
    while (( $# > 0 ))                    #等同于 [ $# -gt 0 ]
    do
        echo $*
        shift
    done
    CTRL+D
    /> . ./test4.sh a b c d e
    a b c d e
    b c d e
    c d e
    d e
    e        

    break命令声明格式:break [n]
    
C语言不同的是,Shellbreak命令携带一个参数,即可以指定退出循环的层数。如果没有指定,其行为和C语言一样,即退出最内层循环。如果指定循环的层数,则退出指定层数的循环体。如果有3层嵌套循环,其中最外层的为1,中间的为2,最里面的是3
    
见如下示例脚本:
    /> cat > test5.sh
    while true
    do
        echo -n "Are you ready to move on?"
        read answer
        if [[ $answer == [Yy] ]]
        then
            break
        else
            echo "Come on."
        fi
    done
    echo "Here we are."
    CTRL+D
    /> . ./test5.sh
    Are you ready to move on?
 y
    Here we are

    continue命令声明格式:continue [n]
    
C语言不同的是,Shellcontinue命令携带一个参数,即可以跳转到指定层级的循环顶部。如果没有指定,其行为和C语言一样,即跳转到最内层循环的顶部。如果指定循环的层数,则跳转到指定层级循环的顶部。如果有3层嵌套循环,其中最外层的为3,中间的为2,最里面的是1
    /> cat  maillist                       #测试数据文件maillist的内容为以下信息。
    stephen
    ann
    sheryl
    mark

    /> cat > test6.sh
    for name in $(cat maillist)
    do
        if [[ $name == stephen ]]; then
            continue
        else
            echo "Hello, $name."
        fi
    done
    CTRL+D
    /> . ./test6.sh
    Hello, ann.
    Hello, sheryl.
    Hello, mark.

    I/O重新定向和子Shell
    
文件中的输入可以通过管道重新定向给一个循环,输出也可以通过管道重新定向给一个文件。Shell启动一个子Shell来处理I/O重新定向和管道。在循环终止时,循环内部定义的任何变量对于脚本的其他部分来说都是不看见的。
    /> cat > demodata                        #为下面的脚本构造册数数据
    abc
    def
    ghi
    CRTL+D
    /> cat > test7.sh
    if (( $# < 1 ))                                #如果脚本参数的数量小于1,则给出错误提示后退出。
    then
        echo "Usage: $0 filename " >&2
        exit 1
    fi
    count=1
    cat $1 | while read line                   #参数一中的文件被cat命令输出后,通过管道逐行输出给while read line
    do
        let $((count == 1)) && echo "Processing file $1..." > /dev/tty  #该行的echo将输出到当前终端窗口。
        echo -e "$count\t$line"              #将输出行号和文件中该行的内容,中间用制表符隔开。
        let count+=1
    done > outfile                               #while循环中所有的输出,除了>/dev/tty之外,其它的全部输出到outfile文件。
    CTRL+D
    /> . ./test7.sh demodata                #只有一行输出,其余的都输出到outfile中了。
    Processing file demodata...
    /> cat outfile
    1       abc
    2       def
    3       ghi

    /> cat > test8.sh
    for i in 9 7 2 3 5 4
    do
        echo $i
    done | sort -n                                #直接将echo的输出通过管道重定向sort命令。
    CTRL+D
    /> . ./test8.sh
    2
    3
    4
    5
    7
    9

你可能感兴趣的:(linux,操作系统,职场,休闲)