Bash流控十二手

在前幾天的的文章中,《[原創]Shell腳本大量示例,你會幾個?》、《[原創]Shell腳本生產示例,你努力學習了嗎?》給大家講解了shell腳本基礎和shell編程的大量實例,如需要查看歷史文章,請點擊公衆號的【文章導航】→ [shell系列文章]查閱,我們在今天的文章中,繼續爲大家帶來shell腳本編程講解!

一、case語句用法演示

case的一個有效用法是提示用戶響應以決定是否繼續進程。這裏提示輸入y以繼續處理,n退出。如果用戶輸入Y、y或yes,處理繼續執行case語句後面部分。如果用戶輸入N、n或no或其他響應,用戶退出腳本。
#!/bin/sh
# caseans.sh
echo -n "Do you wish to proceed [y..n] :"
read ANS
case $ANS in
        y|Y|yes|Yes) echo "yes is selected"
        ;;
        n|N) echo "no is selected"
        exit 0  # no error so only use exit 0 to terminate
        ;;
        *) echo "`basename $0` : Unknow response" >&2
        exit 1
        ;;
esac    
# if we are here then a y|Y|yes|Yes was selected only.
運行腳本,輸入無效響應,得結果:
[root@localhost ~]# ./caseans.sh 
Do you wish to proceed [y..n] :df
caseans.sh : Unknow response
給出有效響應:
[root@localhost ~]# ./caseans.sh 
Do you wish to proceed [y..n] :y
yes is selected

二、case與命令參數傳遞

可以使用case控制到腳本的參數傳遞。下面腳本中,測試特定變量$#,它包含傳遞的參數個數,如果不等於1,退出並顯示可用信息。然後case語句捕獲下列參數: passwd、start、stop或help,相對於每一種匹配模式執行進一步處理腳本。如果均不匹配,顯示可用信息到標準錯誤輸出。
#!/bin/sh
# caseparam.sh
if [ $# != 1 ]; then
        echo "Usage:`basename $0`[start|stop|help]" >&2
        exit 1
fi      
# assign the parameter to the variable OPT
OPT=$1
case $OPT in
        start) echo "starting.. `basename $0`"
        # code here to start a process
        ;;
        stop) echo "stopping.. `basename $0`"
        # code here to stop a process
        ;;
        help) 
        # code here to display a help page
        ;;
        *) echo "Usage:`basename $0`[start|stop|help]"
        ;;
esac
運行腳本,輸入無效參數:
[root@localhost ~]# ./caseparam.sh what
Usage:caseparam.sh[start|stop|help]
輸入有效參數,結果爲:
[root@localhost ~]# ./caseparam.sh stop
stopping.. caseparam.sh

三、case語句捕獲輸入並執行空命令

不一定要在匹配模式後加入命令,如果你原本不想做什麼,只是在進一步處理前過濾出意外響應,這樣做是一種好辦法。如果要運行對應於一個會計部門的帳目報表,必須首先在決定運行報表的類型前確認用戶輸入一個有效的部門號,匹配所有可能值,其他值無效。用case可以很容易實現上述功能。下面的腳本中如果用戶輸入部門號不是234、453、655或454,用戶退出並返回可用信息。一旦響應了用戶的有效部門號,腳本應用同樣的技術取得報表類型,在case語句末尾顯示有效的部門號和報表類型.
#!/bin/sh
# casevaild.sh
echo -n "Enter the account dept No: :"
read ACC
case $ACC in
        234);;
        453);;
        655);;
        454);;
        *) echo "`basename $0`: Unknown dept No:" >&2
        echo "try ... 234,453,655,454"
        exit 1
        ;;
esac
# if we are here, then we have validated the dept no
echo "1 . post"
echo "2 . prior"
echo -n "Enter the type of report:"
read ACC_TYPE
case $ACC_TYPE in
        1) TYPE=post
        ;;
        2) TYPE=prior;;
        *) echo "`basename $0`: Unknown account type." >&2
        exit 1
        ;;
esac
# if we are here the we are validated!
echo "now running report for dept $ACC for the type $TYPE"
# run the command reprot...
輸入有效部門號,該腳本不同運行輸入情況的顯示結果:
[root@localhost ~]# ./casevalid.sh 
Enter the account dept No: :234
1 . post
2 . prior
Enter the type of report:2
now running report for dept 234 for the type prior
輸入無效部門號,該腳本不同運行輸入情況的顯示結果:
[root@localhost ~]# ./casevalid.sh 
Enter the account dept No: :432
casevalid.sh: Unknown dept No:
try ... 234,453,655,454
輸入無效的報表類型,該腳本不同運行輸入情況的顯示結果:
[root@localhost ~]# ./casevalid.sh 
Enter the account dept No: :655
1 . post
2 . prior
Enter the type of report:4
casevalid.sh: Unknown account type.

四、使用case語句實現缺省變量值設定

如果在讀變量時輸入回車鍵,不一定總是退出腳本。可以先測試是否已設置了變量,如果未設置,可以設置該值。下面的腳本中,要求用戶輸入運行報表日期。如果用戶輸入回車鍵,則使用缺省日期星期六,並設置爲變量when的取值。如果用戶輸入另外一天,這一天對於case語句是運行的有效日期,即星期六、星期四、星期一。注意,這裏結合使用了日期縮寫作爲捕獲的可能有效日期。
#!/bin/sh
# caserep.sh
echo "      Weekly Report"
echo -n "What day do you want to run report [Saturday] :"
# if just a return is hit then except default which is Saturday
read WHEN
echo "validating .. ${WHEN:="Saturday"}"
case $WHEN in
        Monday|MONDAY|mon)
        ;;
        Sunday|SUNDAY|sun)
        ;;
        Saturday|SATURDAY|sat)
        ;;
        *)
        echo "Are you nuts! this report can only be run on " >&2
        echo " on a Saturday, Sunday or Monday" >&2
        exit 1
        ;;
esac    
echo "Report to run on $WHEN"
# command here to submitted actual report run
對於正確輸入,執行結果如下:
[root@localhost ~]# ./caserep.sh 
                Weekly Report
What day do you want to run report [Saturday] :
validating .. Saturday
Report to run on Saturday
對於錯誤的輸入,執行結果如下:
[root@localhost ~]# ./caserep.sh 
                Weekly Report
What day do you want to run report [Saturday] :Tuesday
validating .. Tuesday
Are you nuts! this report can only be run on 
on a Saturday, Sunday or Monday

五、簡單的for循環

此例僅顯示列表1 2 3 4 5,用變量名訪問列表
#!/bin/sh
# for_i.sh
for loop in 1 2 3 4 5
do
        echo $loop
done
運行上述腳本,輸出:
[root@localhost ~]# ./for_i.sh 
1
2
3
4
5

六、使用for語句打印字符串列表

下面for循環中,列表包含字符串“orange red blue grey”,命令爲echo,變量名爲loop,echo命令使用$loop反饋出列表中所有取值,直至列表爲空。
#!/bin/sh
# forlist.sh
for loop in "orange red blue grey"
do
        echo "$loop"
done
腳本執行結果:
[root@localhost ~]# ./forlist.sh
orange red blue grey

七、for循環遍歷目錄下的文件

對for循環使用ls命令這個循環執行ls命令,打印當前目錄下所有文件
#!/bin/sh
# forls.sh
for loop in `ls `
do
        echo $loop
done
腳本執行結果如下:
[root@localhost ~]# ./forls.sh
anaconda-ks.cfg
a.sql
a.txt
aw.txt
b.tx
b.txt

八、for循環遍歷參數

在f o r循環中省去i n列表選項時,它將接受命令行位置參數作爲參數。實際上即指明:for params in"$@"或者for params in"$*",下面的例子不使用i n列表選項, for循環查看特定參數$@$*,以從命令行中取得參數
#!/bin/sh
# forparam2
for params
do
        echo "You supplied $params as a command line option"
done
下面的腳本包含in "$@",結果與上面的腳本相同:
#!/bin/sh
# forparam3
for params in "$@"
do
        echo "You supplied $params as a command line option"
done

九、for循環實現查找文件

如果要查看一系列文件,可在for循環裏使用find命令,利用命令行參數,傳遞所有要查閱的文件.
#!/bin/sh
# forfind.sh
for loop
do
        find / -name $loop -print
done

十、使用for循環備份文件

可以用for循環備份所有文件,只需將變量作爲cp命令的目標參數。這裏有一變量.bak,當在循環中使用cp命令時,它作爲此命令目標文件名。列表命令爲ls
#!/bin/sh
# forbak.sh
suffix=".bak"
for loop in `ls `
do
        cp $loop $loop$suffix
done

十一、使用for批量刪除空文件

下面的例子中, sed用於刪除所有空文件,並將輸出導至以.HOLD。 mv爲擴展名的新文件中,mv將這些文件移至初始文件中。
#!/bin/sh
# forsed.sh
for files in `ls LPSO*`
do
        sed -e "/^$/d" $files >$files.HOLD
        mv $files.HOLD $files
done

十二、for循環嵌入示例

下面腳本即爲嵌入for循環,這裏有兩個列表APPS和SCRIPTS。第一個包含服務器上應用的路徑,第二個爲運行在每個應用上的管理腳本。對列表APPS上的每一個應用,列表SCRIPTS裏的腳本將被運行,腳本實際上爲後臺運行。腳本使用tee命令在登錄文件上放一條目,因此輸出到屏幕的同時也輸出到一個文件。查看輸出結果就可以看出嵌入for循環怎樣使用列表SCRIPTS以執行列表APPS上的處理。
#!/bin/sh
# audit_run.sh
APPS="/apps/accts /apps/claims /apps/stock /apps/serv"
SCRIPTS="audit.check report.run cleanup"
LOGFILE=audit.log
MY_DATE=`date +%H:%M" on "%d/%m%Y`
# outer loop
for loop in $APPS
do      
        # inner loop
        for loop2 in $SCRIPTS
        do      
                echo "system $loop now running $loop2 at $MY_DATE" | tee -a\
                 $LOGFILE $loop $loop2 &
         done    
done
程序的運行結果如下:
tee: /apps/accts: No such file or directory
tee: /apps/accts: No such file or directory
system /apps/accts now running report.run at 20:18 on 21/112010
tee: /apps/accts: No such file or directory
system /apps/accts now running cleanup at 20:18 on 21/112010
tee: /apps/claims: No such file or directory
system /apps/claims now running audit.check at 20:18 on 21/112010
tee: /apps/claims: No such file or directory
system /apps/claims now running report.run at 20:18 on 21/112010
tee: /apps/claims: No such file or directory
system /apps/claims now running cleanup at 20:18 on 21/112010
tee: /apps/stock: No such file or directory
system /apps/stock now running audit.check at 20:18 on 21/112010
tee: /apps/stock: No such file or directory
system /apps/stock now running report.run at 20:18 on 21/112010
tee: /apps/stock: No such file or directory
system /apps/stock now running cleanup at 20:18 on 21/112010
tee: /apps/serv: No such file or directory
system /apps/serv now running audit.check at 20:18 on 21/112010
[root@localhost ~]# system /apps/accts now running audit.check at 20:18 on 21/112010
tee: /apps/serv: No such file or directory
system /apps/serv now running report.run at 20:18 on 21/112010
tee: /apps/serv: No such file or directory
system /apps/serv now running cleanup at 20:18 on 21/112010


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章