5.  IFS和循环:
    Shell
的内部域分隔符可以是空格、制表符和换行符。它可以作为命令的分隔符用在例如readsetfor等命令中。如果在列表中使用不同的分隔符,用户可以自己定义这个符号。在修改之前将IFS原始符号的值保存在另外一个变量中,这样在需要的时候还可以还原。
    
见如下示例脚本:
    /> cat > test9.sh
    names=Stephen:Ann:Sheryl:John   #names变量包含的值用冒号分隔。
    oldifs=$IFS                                   #保留原有IFSoldifs变量,便于后面的还原。
    IFS=":"                            
    for friends in $names                     #这是遍历以冒号分隔的names变量值。    
    do
        echo Hi $friends
    done
    IFS=$oldifs                                   #IFS还原为原有的值。
    set Jerry Tom Angela
    for classmates in $*                      #再以原有IFS的值变量参数列表。
    do
        echo Hello $classmates
    done
    CTRL+D
    /> . ./test9.sh
    Hi Stephen
    Hi Ann
    Hi Sheryl
    Hi John
    Hello Jerry
    Hello Tom
    Hello Angela

    6.  函数:
    Shell
中函数的职能以及优势和C语言或其它开发语言基本相同,只是语法格式上的一些差异。下面是Shell中使用函数的一些基本规则:
    1)
函数在使用前必须定义。
    2)
函数在当前环境下运行,它和调用它的脚本共享变量,并通过位置参量传递参数。而该位置参量将仅限于该函数,不会影响到脚本的其它地方。
    3)
通过local函数可以在函数内建立本地变量,该变量在出了函数的作用域之后将不在有效。
    4)
函数中调用exit,也将退出整个脚本。
    5)
函数中的return命令返回函数中最后一个命令的退出状态或给定的参数值,该参数值的范围是0-256之间。如果没有return命令,函数将返回最后一个Shell的退出值。
    6)
如果函数保存在其它文件中,就必须通过sourcedot命令把它们装入当前脚本。
    7)
函数可以递归。
    8)
将函数从Shell中清空需要执行:unset -f function_name
    9)
将函数输出到子Shell需要执行:export -f function_name
    10)
可以像捕捉Shell命令的返回值一样获取函数的返回值,如$(function_name)
    Shell
中函数的声明格式如下:
    function function_name { command; command; }
    
见如下示例脚本:
    /> cat > test1.sh
    function increment() {            #定义函数increment
        local sum                           #定义本地变量sum
        let "sum=$1+1"    
        return $sum                      #返回值是sum的值。
    }
    echo -n "The num is "
    increment 5                          #increment函数调用。
    echo $?                                #输出increment函数的返回值。
    CTRL+D
    /> . ./test1.sh
    The num is 6

    7.  陷阱信号(trap)
    
Shell程序运行的时候,可能收到各种信号,有的来自于操作系统,有的来自于键盘,而该Shell在收到信号后就立刻终止运行。但是在有些时候,你可能并不希望在信号到达时,程序就立刻停止运行并退出。而是他能希望忽略这个信号而一直在运行,或者在退出前作一些清除操作。trap命令就允许你控制你的程序在收到信号以后的行为。
    
其格式如下:
    trap 'command; command' signal-number
    trap 'command; command' signal-name
    trap signal-number  
    trap signal-name
    
后面的两种形式主要用于信号复位,即恢复处理该信号的缺省行为。还需要说明的是,如果trap后面的命令是使用单引号括起来的,那么该命令只有在捕获到指定信号时才被执行。如果是双引号,则是在trap设置时就可以执行变量和命令替换了。
    
下面是系统给出的信号数字和信号名称的对照表:
    1)SIGHUP 2)SIGINT 3)SIGQUIT 4)SIGILL 5)SIGTRAP 6)SIGABRT 7)SIGBUS 8)SIGFPE
    9)SIGKILL 10) SIGUSR1 11)SIGEGV 12)SIGUSR2 13)SIGPIPE 14)SIGALRM 15)SIGTERM 17)SIGCHLD
    18)SIGCONT 19)SIGSTOP ... ...
    
见如下示例脚本:
    /> trap 'rm tmp*;exit 1' 1 2 15      #该命令表示在收到信号1215时,该脚本将先执行rm tmp*,然后exit 1退出脚本。
    /> trap 2                                      #当收到信号2时,将恢复为以前的动作,即退出。
    /> trap " " 1 2                              #当收到信号12时,将忽略这两个信号。
    /> trap -                                      #表示恢复所有信号处理的原始值。
    /> trap 'trap 2' 2                           #在第一次收到信号2时,执行trap 2,这时将信号2的处理恢复为缺省模式。在收到信号2时,Shell程序退出。
    /> cat > test2.sh
    trap 'echo "Control+C will not terminate $0."' 2   #捕获信号2,即在键盘上按CTRL+C
    trap 'echo "Control+\ will not terminate $0."' 3   #捕获信号3,即在键盘上按CTRL+\
    echo "Enter stop to quit shell."
    while true                                                        #无限循环。
    do
        echo -n "Go Go...."
        read
        if [[ $REPLY == [Ss]top ]]                            #直到输入stopStop才退出循环和脚本。
       then
            break
        fi
    done
    CTRL+D
    /> . ./test2.sh
    Enter stop to quit shell.
    Go Go....^CControl+C will not terminate -bash.
    ^\Control+\ will not terminate -bash.
    stop