亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
123下一頁
最近訪問板塊 發(fā)新帖
查看: 290520 | 回復(fù): 21
打印 上一主題 下一主題

shell基礎(chǔ)第十八篇-控制流結(jié)構(gòu) [復(fù)制鏈接]

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2010-11-20 14:44 |只看該作者 |倒序瀏覽
本帖最后由 L_kernel 于 2010-11-20 14:46 編輯

所有功能腳本必須有能力進(jìn)行判斷,也必須有能力基于一定條件處理相關(guān)命令。本章講
述這方面的功能,在腳本中創(chuàng)建和應(yīng)用控制結(jié)構(gòu)。
本章內(nèi)容有:
• 退出狀態(tài)。
• while、f o r和until loops循環(huán)。
• if then else語句。
• 腳本中動作。
• 菜單。

退出狀態(tài)
在書寫正確腳本前,大概講一下退出狀態(tài)。任何命令進(jìn)行時都將返回一個退出狀態(tài)。如
果要觀察其退出狀態(tài),使用最后狀態(tài)命令:
$ echo $?
主要有4種退出狀態(tài)。前面已經(jīng)講到了兩種,即最后命令退出狀態(tài)$ ?和控制次序命令( $ $、
| |)。其余兩種是處理s h e l l腳本或s h e l l退出及相應(yīng)退出狀態(tài)或函數(shù)返回碼。在第1 9章講到函數(shù)
時,也將提到其返回碼。
要退出當(dāng)前進(jìn)程,s h e l l提供命令e x i t,一般格式為:
exit n
其中,n為一數(shù)字。
如果只在命令提示符下鍵入e x i t,假定沒有在當(dāng)前狀態(tài)創(chuàng)建另一個s h e l l,將退出當(dāng)前s h e l l。
如果在腳本中鍵入e x i t,s h e l l將試圖(通常是這樣)返回上一個命令返回值。有許多退出腳本
值,但其中相對于腳本和一般系統(tǒng)命令最重要的有兩種,即:
退出狀態(tài)0 退出成功,無錯誤。
退出狀態(tài)1 退出失敗,某處有錯誤。
可以在s h e l l腳本中加入自己的退出狀態(tài)(它將退出腳本)。本書鼓勵這樣做,因為另一個
s h e l l腳本或返回函數(shù)可能要從s h e l l腳本中抽取退出腳本。另外,相信加入腳本本身的退出腳
本值是一種好的編程習(xí)慣。
如果愿意,用戶可以在一個用戶輸入錯誤后或一個不可覆蓋錯誤后或正常地處理結(jié)束后
退出腳本。
注意從現(xiàn)在起,本書所有腳本都將加入注釋行。注釋行將解釋腳本具體含義,幫助用戶
理解腳本?梢栽谌魏蔚胤郊尤胱⑨屝,因為其本身被解釋器忽略。注釋行應(yīng)以#開頭。

控制結(jié)構(gòu)
幾乎所有的腳本里都有某種流控制結(jié)構(gòu),很少有例外。流控制是什么?假定有一個腳本
包含下列幾個命令:
  1. #!/bin/sh
  2. # make a directory
  3. mkdir /home/dave/mydocs
  4. # copy all doc files
  5. cp *.docs /home/dave/docs
  6. # delete all doc files
  7. rm *.docs
復(fù)制代碼
上述腳本問題出在哪里?如果目錄創(chuàng)建失敗或目錄創(chuàng)建成功文件拷貝失敗,如何處理?
這里需要從不同的目錄中拷貝不同的文件。必須在命令執(zhí)行前或最后的命令退出前決定處理
方法。s h e l l會提供一系列命令聲明語句等補(bǔ)救措施來幫助你在命令成功或失敗時,或需要處
理一個命令清單時采取正確的動作。
這些命令語句大概分兩類:
循環(huán)和流控制。


流控制
i f、t h e n、e l s e語句提供條件測試。測試可以基于各種條件。例如文件的權(quán)限、長度、數(shù)
值或字符串的比較。這些測試返回值或者為真( 0),或者為假( 1);诖私Y(jié)果,可以進(jìn)行
相關(guān)操作。在講到條件測試時已經(jīng)涉及了一些測試語法。
c a s e語句允許匹配模式、單詞或值。一旦模式或值匹配,就可以基于這個匹配條件作其他
聲明。


循環(huán)
循環(huán)或跳轉(zhuǎn)是一系列命令的重復(fù)執(zhí)行過程,本書提到了3種循環(huán)語句:
for 循環(huán)每次處理依次列表內(nèi)信息,直至循環(huán)耗盡。
Until 循環(huán)此循環(huán)語句不常使用, u n t i l循環(huán)直至條件為真。條件部分在循環(huán)末尾部分。
While 循環(huán)w h i l e循環(huán)當(dāng)條件為真時,循環(huán)執(zhí)行,條件部分在循環(huán)頭。
流控制語句的任何循環(huán)均可嵌套使用,例如可以在一個f o r循環(huán)中嵌入另一個f o r循環(huán)。
現(xiàn)在開始講解循環(huán)和控制流,并舉一些腳本實例。
從現(xiàn)在起,腳本中e c h o語句使用L I N U X或B S D版本,也就是說使用e c h o方法echo -e -n,
意即從e c h o結(jié)尾中下一行執(zhí)行命令。應(yīng)用于U N I X(系統(tǒng)V和B S D)的統(tǒng)一的e c h o命令參閱1 9
章s h e l l函數(shù)。

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
2 [報告]
發(fā)表于 2010-11-20 15:38 |只看該作者
grep輸出檢查
不必拘泥于變量或數(shù)值測試,也可以測知系統(tǒng)命令是否成功返回。對g r e p使用i f語句找出
g r e p是否成功返回信息。下面的例子中g(shù) r e p用于查看D a v e是否在數(shù)據(jù)文件d a t a . f i l e中,注意
‘D a v e \ >’用于精確匹配。
  1. [root@localhost ~]# cat grepif.sh
  2. #!/bin/sh
  3. # grepif.sh
  4. if grep 'Dave\>' data.file > /dev/null 2>&1
  5. then
  6.                 echo "Great Dave is in the file"
  7. else
  8.                 echo "No Dave is not in the file"
  9. fi
  10. [root@localhost ~]# ./grepif.sh
  11. No Dave is not in the file
復(fù)制代碼
用變量測試grep輸出
正像前面看到的,可以用g r e p作字符串操作。下面的腳本中,用戶輸入一個名字列表,
g r e p在變量中查找,要求其包含人名P e t e r。
下面是具體的代碼情況和運行信息。
  1. [root@localhost ~]# cat grepstr.sh
  2. #!/bin/sh
  3. # grepstr
  4. echo -n "Enter a list of names:"
  5. read list
  6. if echo $list | grep "Peter" > /dev/null 2>&1
  7. then
  8.                 echo "Peter is here"
  9.                 # could do some processing here...
  10. else
  11.                 echo "Peter's not in the list. No comment!"
  12. fi
  13. [root@localhost ~]# ./grepstr.sh
  14. Enter a list of names:John Louise Peter James
  15. Peter is here
復(fù)制代碼
文件拷貝輸出檢查
下面測試文件拷貝是否正常,如果c p命令并沒有拷貝文件m y f i l e到m y f i l e . b a k,則打印錯
誤信息。注意錯誤信息中` basename $0`打印腳本名。
如果腳本錯誤退出,一個好習(xí)慣是顯示腳本名并將之定向到標(biāo)準(zhǔn)錯誤中。用戶應(yīng)該知道
產(chǎn)生錯誤的腳本名。
  1. [root@localhost ~]# cat ifcp.sh
  2. #!/bin/sh
  3. # ifcp.sh
  4. if cp myfile myfile.bak; then
  5.                 echo "good copy"
  6. else
  7.                 echo "`basename $0`: error could not copy the file" >&2
  8. fi
  9. [root@localhost ~]# ./ifcp.sh
  10. cp: cannot stat `myfile': No such file or directory
  11. ifcp.sh: error could not copy the file
復(fù)制代碼
注意,文件可能沒找到,系統(tǒng)也產(chǎn)生本身的錯誤信息,這類錯誤信息可能與輸出混在一
起。既然已經(jīng)顯示系統(tǒng)錯誤信息獲知腳本失敗,就沒必要顯示兩次。要去除系統(tǒng)產(chǎn)生的錯誤
和系統(tǒng)輸出,只需簡單的將標(biāo)準(zhǔn)錯誤和輸出重定向即可。修改腳本為: >/dev/null 2>&1。
  1. [root@localhost ~]# cat ifcp.sh
  2. #!/bin/sh
  3. # ifcp.sh
  4. if cp myfile myfile.bak > /dev/null 2>&1; then
  5.                 echo "good copy"
  6. else
  7.                 echo "`basename $0`: error could not copy the file" >&2
  8. fi
  9. [root@localhost ~]# ./ifcp.sh
  10. ifcp.sh: error could not copy the file
復(fù)制代碼
上面當(dāng)中>/dev/null表示任何標(biāo)準(zhǔn)輸出都定向到那個無盡的“黑洞”/de/null中,然后2>&1表示
錯誤輸出也是到/dev/null中,&1表示前面的那個/dev/null,腳本運行時,所有輸出包括錯誤重定向至系統(tǒng)垃圾堆。

當(dāng)前目錄測試
當(dāng)運行一些管理腳本時,可能要在根目錄下運行它,特別是移動某種全局文件或進(jìn)行權(quán)
限改變時。一個簡單的測試可以獲知是否運行在根目錄下。下面腳本中變量D I R E C TO RY使用
當(dāng)前目錄的命令替換操作,然后此變量值與" / "字符串比較( /為根目錄)。如果變量值與字符
串不等,則用戶退出腳本,退出狀態(tài)為1意味錯誤信息產(chǎn)生。
  1. [root@localhost ~]# cat ifpwd.sh
  2. #!/bin/sh
  3. # ifpwd.sh
  4. DIRECTORY=`pwd`
  5. # grab the current dirctory
  6. if [ "$DIRECTORY" != "/" ]; then
  7.                 # is it the root directory ?
  8.                 # no, the direct output to standard error, which is the screen
  9.                 # by default.
  10.                 echo "You need to be in the root directory no $DIRECTORY to run
  11.                 this script" >&2
  12.                 # exit with a value of 1, an error
  13.                 exit 1
  14. fi
  15. [root@localhost ~]# ./ifpwd.sh
  16. You need to be in the root directory no /root to run
  17.                 this script
復(fù)制代碼
文件權(quán)限測試
可以用i f語句測試文件權(quán)限,下面簡單測試文件t e s t . t x t是否被設(shè)置到變量L O G N A M E,測試test.txt文件是否具有寫的權(quán)限。下面的腳本先建立一個test.txt的空白文檔,列出它的相關(guān)權(quán)限。然后執(zhí)行腳本測試其是否可以寫入,然后顯示相關(guān)信息。
  1. [root@localhost ~]# touch test.txt
  2. [root@localhost ~]# ls -l test.txt
  3. -rw-r--r-- 1 root root 0 Nov 21 15:21 test.txt
  4. [root@localhost ~]# chmod u+x ifwr.sh
  5. [root@localhost ~]# cat ifwr.sh
  6. #!/bin/sh
  7. # ifwr.sh
  8. LOGFILE=test.txt
  9. echo $LOGFILE
  10. if [ ! -w "$LOGFILE" ]; then
  11.                 echo " You cannot write to $LOGFILE" >&2
  12. else
  13.                 echo " You can write to $LOGFILE" >&2
  14. fi
  15. [root@localhost ~]# ./ifwr.sh
  16. test.txt
  17. You can write to test.txt
復(fù)制代碼
測試傳遞到腳本中的參數(shù)
i f語句可用來測試傳入腳本中參數(shù)的個數(shù)。使用特定變量$ #,表示調(diào)用參數(shù)的個數(shù)?梢
測試所需參數(shù)個數(shù)與調(diào)用參數(shù)個數(shù)是否相等。
以下測試確保腳本有三個參數(shù)。如果沒有,則返回一個可用信息到標(biāo)準(zhǔn)錯誤,然后代碼
退出并顯示退出狀態(tài)。如果參數(shù)數(shù)目等于3,則顯示所有參數(shù)。
  1. [root@localhost ~]# cat ifparam.sh
  2. #!/bin/sh
  3. # ifparam
  4. if [ $# -lt 3 ]; then
  5.                 # less than 3 parameters called, echo a usage message and exit
  6.                 # 如果少于三個參數(shù)則顯示使用的信息,然后退出。
  7.                 echo "Usage: `basename $0`arg1 arg2 arg3" >&2
  8.                 exit 1
  9. fi
  10. # good, received 3 params, let's echo them
  11. # 好,現(xiàn)在接受了三個參數(shù),讓我們開始顯示他們
  12. echo "arg1: $1"
  13. echo "arg2: $2"
  14. echo "arg3: $3"
  15. [root@localhost ~]# ./ifparam.sh cup medal
  16. Usage: ifparam.sharg1 arg2 arg3
  17. [root@localhost ~]# ./ifparam.sh cup medal trophy
  18. arg1: cup
  19. arg2: medal
  20. arg3: trophy
復(fù)制代碼
從上面的運行信息可以看出,如果只傳入兩個參數(shù),則顯示一可用信息,然后腳本退出。
只有正確傳入了三個參數(shù)了,才顯示所有的參數(shù)然后退出。

決定腳本是否為交互模式
有時需要知道腳本運行是交互模式(終端模式)還是非交互模式( c r o n或a t)。腳本也許
需要這個信息以決定從哪里取得輸入以及輸出到哪里,使用t e s t命令并帶有- t選項很容易確認(rèn)
這一點。如果t e s t返回值為1,則為交互模式。假如我是在一個終端下運行下面這個腳本。
  1. [root@localhost ~]# cat ifinteractive.sh
  2. #!/bin/sh
  3. # ifinteractive.sh
  4. if [ -t ]; then
  5.                 echo "We are interactive with a terminal"
  6. else
  7.                 echo "We must be running from some background process probably
  8.                 cron or at"
  9. fi
  10. [root@localhost ~]# ./ifinteractive.sh
  11. We are interactive with a terminal
復(fù)制代碼
簡單的if else語句
下一個i f語句有可能是使用最廣泛的:
if 條件
t h e n
命令1
e l s e
命令2
f i
使用i f語句的e l s e部分可在條件測試為假時采取適當(dāng)動作。

變量設(shè)置測試
下面的例子測試環(huán)境變量E D I TO R是否已設(shè)置。如果E D I TO R變量為空,將此信息通知用
戶。如果已設(shè)置,在屏幕上顯示編輯類型。
  1. [root@localhost ~]# cat ifeditor.sh
  2. #!/bin/sh
  3. # ifeditor.sh
  4. if [ -z $EDITOR ]; then
  5.                 # the variable has not been set
  6.                 # 變量沒有設(shè)置
  7.                 echo "Your EDITOR environment is not set"
  8. else
  9.                 # let's see what it is
  10.                 # 如果設(shè)置了,讓我們來看看它到底是什么
  11.                 echo "Using $EDITOR as the default editor"
  12. fi
  13. [root@localhost ~]# ./ifeditor.sh
  14. Your EDITOR environment is not set
復(fù)制代碼

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
3 [報告]
發(fā)表于 2010-11-20 16:10 |只看該作者
將腳本參數(shù)傳入系統(tǒng)命令
可以向腳本傳遞位置參數(shù),然后測試變量。這里,如果用戶在腳本名字后鍵入目錄名,
腳本將重設(shè)$ 1特殊變量為一更有意義的名字。即D I R E C TO RY。這里需測試目錄是否為空,如
果目錄為空,ls -A將返回空,然后對此返回一信息。
  1. # ifdirec.sh
  2. # assigning $1 to DIRECTORY variable
  3. DIRECTORY=$1
  4. if [ "`ls -A $DIRECTORY`" == "" ]; then
  5.         # if it's an empty string, then it's empty
  6.         echo "$DIRECTORY is indeed empty"
  7. else   
  8.         # otherwise it is not
  9.         echo "$DIRECTORY is not empty"
  10. fi
復(fù)制代碼
也可以使用下面的腳本替代上面的例子并產(chǎn)生同樣的結(jié)果。
  1. [root@localhost ~]# cat ifdirec2.sh
  2. #!/bin/sh
  3. # ifdirec2
  4. DIRECTORY=$1
  5. if [ -z "`ls -A $DIRECTORY`" ]
  6. then
  7.                 echo "$DIRECTORY is indeed empty"
  8. else
  9.                 echo "$DIRECTORY is not empty"
  10. fi
復(fù)制代碼
null:命令用法
到目前為止,條件測試已經(jīng)講完了t h e n和e l s e部分,有時也許使用者并不關(guān)心條件為真或
為假。
不幸的是i f語句各部分不能為空—一些語句已經(jīng)可以這樣做。為解決此問題, s h e l l提供
了:空命令。空命令永遠(yuǎn)為真(也正是預(yù)想的那樣);氐角懊娴睦樱绻夸洖榭,可以
只在t h e n部分加入命令。
  1. [root@localhost ~]# cat ifdirectory.sh
  2. #!/bin/sh
  3. # ifdirectory.sh
  4. DIRECTORY=$1
  5. if [ "`ls -A $DIRECTORY`" == "" ]
  6. then
  7.                 echo "$DIRECTORY is indeed empty"
  8. else :
  9.                 # do nothing
  10. fi
  11. [root@localhost ~]# ./ifdirectory.sh testd
  12. testd is indeed empty
復(fù)制代碼
測試目錄創(chuàng)建結(jié)果
現(xiàn)在繼續(xù)討論目錄,下面的腳本接受一個參數(shù),并用之創(chuàng)建目錄,然后參數(shù)被傳入命令
行,重設(shè)給變量D I R E C TO RY,最后測試變量是否為空。
if ["$DIRECTORY"=""]
也可以用
if[$# -lt 1]
來進(jìn)行更普遍的參數(shù)測試。
如果字符串為空,返回一可用信息,腳本退出。如果目錄已經(jīng)存在,腳本從頭至尾走一
遍,什么也沒做。
創(chuàng)建前加入提示信息,如果鍵入Y或y,則創(chuàng)建目錄,否則使用空命令表示不采取任何動作。
使用最后命令狀態(tài)測試創(chuàng)建是否成功執(zhí)行,如果失敗,返回相應(yīng)信息。
  1. [root@localhost ~]# cat ifmkdir.sh
  2. #!/bin/sh
  3. # ifmkdir.sh
  4. # parameter is passed as $1 but reassigned to DIRECTORY
  5. DIRECTORY=$1
  6. # is the string empty ??
  7. if [ "$DIRECTORY" == "" ]
  8. then
  9.                 echo "Usage :`basename $0` directory to create" >&2
  10.                 exit 1
  11. fi
  12. if [ -d $DIRECTORY ]
  13. then : # do nothing
  14. else
  15.                 echo "The directory does not exist"
  16.                 echo -n "Create it now? [y..n] :"
  17.                 read ANS
  18.                 if [ "$ANS" == "y" ] || [ "$ANS" == "Y" ]
  19.                 then
  20.                                 echo "creating now"
  21.                                 # create directory and send all output to /dev/null
  22.                                 mkdir $DIRECTORY > /dev/null 2>&1
  23.                                 if [ $? != 0 ]; then
  24.                                                 echo "Errors creating the directory $DIRECTORY" >&2
  25.                                                 exit 1
  26.                                 fi
  27.                 else : # do nothing
  28.                 fi
  29. fi
  30. [root@localhost ~]# ./ifmkdir.sh dt
  31. The directory does not exist
  32. Create it now? [y..n] :y
  33. creating now
復(fù)制代碼
另一個拷貝實例
在另一個拷貝實例中,腳本傳入兩個參數(shù)(應(yīng)該包含文件名),系統(tǒng)命令c p將$ 1拷入$ 2,
輸出至/ d e v / n u l l。如果命令成功,則仍使用空命令并且不采取任何動作。
另一方面,如果失敗,在腳本退出前要獲知此信息。
  1. [root@localhost ~]# cat ifcp2.sh
  2. #!/bin/sh
  3. # ifcp2.sh
  4. if cp $1 $2 > /dev/null 2>&1
  5.                 # successful, great do nothing
  6. then :
  7. else
  8.                 # oh dear, show the user what files they were.
  9.                 echo "`basename $0`: ERROR failed to copy $1 to $2"
  10.                 exit 1
  11. fi
  12. [root@localhost ~]# ./ifcp2.sh myfile.lex myfile.lex.bak
  13. ifcp2.sh: ERROR failed to copy myfile.lex to myfile.lex.bak
  14. [root@localhost ~]# touch myfile.lex
  15. [root@localhost ~]# ./ifcp2.sh myfile.lex myfile.lex.bak
復(fù)制代碼
上面展現(xiàn)了腳本運行成功和腳本運行失敗的情況。

下面的腳本用s o r t命令將文件a c c o u n t s . q t r分類,并輸出至系統(tǒng)垃圾堆。沒人愿意觀察屏幕
上3 0 0行的分類頁。成功之后不采取任何動作。如果失敗,通知用戶。
  1. [root@localhost ~]# cat ifsort.sh
  2. #!/bin/sh
  3. # ifsort
  4. if sort accounts.qtr > /dev/null
  5.                 # sorted. Great
  6. then :
  7. else
  8.                 # better let the user know
  9.                 echo "`basename $0`: Oops..errors could not sort accounts.qtr"
  10. fi
復(fù)制代碼
多個if語句
可能有時要嵌入i f語句。為此需注意i f和f i的相應(yīng)匹配使用。

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
4 [報告]
發(fā)表于 2010-11-20 16:40 |只看該作者
測試和設(shè)置環(huán)境變量
前面已經(jīng)舉例說明了如何測試環(huán)境變量E D I TO R是否被設(shè)置。現(xiàn)在如果未設(shè)置,則進(jìn)一步
為其賦值,腳本如下:
  1. #!/bin/sh
  2. # ifseted.sh
  3. # is the EDITOR set?
  4. if [ -z $EDITOR ]; then
  5.         echo "Your EDITOR environment is not set"
  6.         echo "I will assum you want to use vi .. OK"
  7.         echo -n "Do you wish to change it now? [y..n] :"
  8.         read ANS

  9.         # check for an upper or lower case 'y'
  10.         if [ "$ANS" == "Y" ] || [ "$ANS" == "y" ]; then
  11.                 echo "enter you  editor type :"
  12.                 read EIDTOR
  13.                 if [ -z $EDITOR ] || [ "$EDITOR" == "" ]; then
  14.                         # if EDITOR not set and no value in variable EDITOR,
  15.                         # then set it to vi
  16.                         echo "No, editor entered, using vi as default"
  17.                         EDITOR=vi
  18.                         export EDITOR
  19.                 fi
  20.                 # got a value use it for EDITOR
  21.                 EDITOR=$EDITOR
  22.                 export EDITOR
  23.                 echo "setting $EDITOR"
  24.         fi
  25. else
  26.         # user
  27.         echo "Using vi as the default editor"
  28.         EDITOR=vi
  29.         export EDITOR
  30. fi
復(fù)制代碼
腳本工作方式如下:首先檢查是否設(shè)置了該變量,如果已經(jīng)賦值,輸出信息提示使用v i作
為缺省編輯器。v i被設(shè)置為編輯器,然后腳本退出。
如果未賦值,則提示用戶,詢問其是否要設(shè)置該值。檢驗用戶輸入是否為大寫或小寫y,
輸入為其他值時,腳本退出。
如果輸入Y或y,再提示輸入編輯類型。使用$ E D I TO R =“”測試用戶是否未賦值和未點
擊r e t u r n鍵。一種更有效的方法是使用-z $EDITO R方法,本文應(yīng)用了這兩種方法。如果測試
失敗,返回信息到屏幕,即使用v i做缺省編輯器,因而E D I TO R賦值為v i。
如果用戶輸入了一個名字到變量E D I TO R,則使用它作為編輯器并馬上讓其起作用,即導(dǎo)
出變量E D I TO R。

檢測最后命令狀態(tài)
前面將目錄名傳入腳本創(chuàng)建了一個目錄,腳本然后提示用戶是否應(yīng)創(chuàng)建目錄。下面的例
子創(chuàng)建一個目錄,并從當(dāng)前目錄將所有* . t x t文件拷入新目錄。但是這段腳本中用最后狀態(tài)命
令檢測了每一個腳本是否成功執(zhí)行。如果命令失敗則通知用戶。
  1. #!/bin/sh
  2. # ifmkdir2.sh
  3. DIR_NAME=testdirec
  4. # where are we?
  5. THRER=`pwd`
  6. # send all output to the system dustbin
  7. mkdir $DIR_NAME > /dev/null 2>&1
  8. # is it a directory ?
  9. if [ -d $DIR_NAME ]; then
  10.         # can we cd to the directory
  11.         cd $DIR_NAME
  12.         if [ $? == 0 ]; then
  13.                 # yes we can
  14.                 HERE=`pwd`
  15.                 cp $THERE/*.txt $HERE
  16.         else
  17.                 echo "Cannot cd to $DIR_NAME" >&2
  18.                 exit 1
  19.         fi
  20. else
  21.         echo "Cannnot create directory $DIR_NAME" >&2
  22.         exit 1
  23. fi
復(fù)制代碼
增加和檢測整數(shù)值
下面的例子進(jìn)行數(shù)值測試。腳本包含了一個計數(shù)集,用戶將其賦予一個新值就可改變它。
腳本然后將當(dāng)前值1 0 0加入一個新值。工作流程如下:
用戶輸入一個新值改變其值,如果鍵入回車鍵,則不改變它,打印當(dāng)前值,腳本退出。
如果用戶用y或Y響應(yīng)新值,將提示用戶輸入增量。如果鍵入回車鍵,原值仍未變。鍵入
一個增量,首先測試是否為數(shù)字,如果是,加入計數(shù)C O U N TO R中,最后顯示新值。
  1. #!/bin/sh
  2. # ifcounter.sh
  3. COUNTER=100
  4. echo "Do you wish to change the counter value currently set at $COUNTER
  5.     [y..n] :"
  6. read ANS
  7. if [ "$ANS" == "y" ] || [ "$ANS" == "Y" ]; then
  8.         # yes user wants to change the value
  9.         echo "Enter a sensible value "
  10.         read VALUE
  11.         # simple test to see if it's numeric, add any number to VALUE,
  12.         # then check out return
  13.         # code
  14.         expr $VALUE + 10 > /dev/null 2>&1
  15.         STATUS=$?
  16.         # check return code of expr
  17.         if [ "$VALUE" == "" ] || [ "$STATUS" != "0" ]; then
  18.                 # send errors to standard error
  19.                 echo " You either entered nothing or a non-numeric " >&2
  20.                 echo " Sorry now exiting...counter stays at $COUNTER" >&2
  21.                 exit 1
  22.         fi      
  23.         # if we are here, then it's a number, so add it to COUNTER
  24.         COUNTER=`expr $COUNTER + $VALUE`
  25.         echo " Counter now set to $COUNTER"
  26. else   
  27.         # if we are here user just hit return instead of entering a number
  28.         # or anssered n to the change a value prompt
  29.         echo " Counter stays at $COUNTER"
  30. fi      
復(fù)制代碼
下面是程序的運行結(jié)果:
  1. [root@localhost ~]# ./ifcounter.sh
  2. Do you wish to change the counter value currently set at 100
  3.         [y..n] :
  4. n
  5. Counter stays at 100
  6. [root@localhost ~]# ./ifcounter.sh
  7. Do you wish to change the counter value currently set at 100
  8.         [y..n] :
  9. y
  10. Enter a sensible value
  11. fdg
  12. You either entered nothing or a non-numeric
  13. Sorry now exiting...counter stays at 100
  14. [root@localhost ~]# ./ifcounter.sh
  15. Do you wish to change the counter value currently set at 100
  16.         [y..n] :
  17. y
  18. Enter a sensible value
  19. 250
  20. Counter now set to 350
復(fù)制代碼

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報告]
發(fā)表于 2010-11-20 17:08 |只看該作者
以下是用戶登錄時啟動應(yīng)用前加入相應(yīng)安全限制功能的基本框架。首先提示輸入用戶名
和密碼,如果用戶名和密碼均匹配腳本中相應(yīng)字符串,用戶登錄成功,否則用戶退出。
腳本首先設(shè)置變量為假—總是假定用戶輸入錯誤, s t t y當(dāng)前設(shè)置被保存,以便隱藏
p a s s w d域中字符,然后重新保存s t t y設(shè)置。
如果用戶I D和密碼正確(密碼是easypasswd),明亮I N VA L I D U S E R和I N VA L I D PA S S W D設(shè)
置為n o表示有效用戶或密碼,然后執(zhí)行測試,如果兩個變量其中之一為y e s,缺省情況下,腳
本退出用戶。
鍵入有效的I D和密碼,用戶將允許進(jìn)入。這是一種登錄腳本的基本框架。下面的例子中
有效用戶I D為root。
提示:在實際中千萬不要這么做,任何人都知道用root身份進(jìn)行測試是很危險的。
  1. #!/bin/sh
  2. # ifpass.sh
  3. # set the variables to false
  4. INVALID_USER=yes
  5. INVALID_PASSWD=yes
  6. # save the current stty settings
  7. SAVEDSTTY=`stty -g`
  8. echo "You are logging into a sensitive area"
  9. echo -n "Enter your ID name :"
  10. read NAME
  11. # hide the characters typed in
  12. stty -echo
  13. echo "Enter your password :"
  14. read PASSWORD
  15. # back on again
  16. stty $SAVEDSTTY
  17. if [ "$NAME" == "root" ]; then
  18.         # if a valid then set variable
  19.         INVALID_USER=no
  20. fi      
  21. if [ "$PASSWORD" == "easypasswd" ]; then
  22.         # if valid password then set variable
  23.         INVALID_PASSWD=no
  24. fi      
  25. if [ "$INVALID_USER" == "yes" -o "$INVALID_PASSWD" == "yes" ]; then
  26.         echo "`basename $0 :` Sorry wrong password or userid"
  27.         exit 1
  28. fi      
  29. # if we get here then their ID and password are OK.
  30. echo "correct user id an password given"
復(fù)制代碼
下面是對應(yīng)兩種不同情況的輸出結(jié)果。
  1. [root@localhost ~]# ./ifpass.sh
  2. You are logging into a sensitive area
  3. Enter your ID name :root
  4. Enter your password :
  5. correct user id an password given
  6. [root@localhost ~]# ./ifpass.sh
  7. You are logging into a sensitive area
  8. Enter your ID name :root
  9. Enter your password :
  10. ifpass.sh Sorry wrong password or userid
復(fù)制代碼
elif用法
if then else語句的e l i f部分用于測試兩個以上的條件。

使用elif進(jìn)行多條件檢測
使用一個簡單的例子,測試輸入腳本的用戶名。腳本首先測試是否輸入一個名字,如果
沒有,則什么也不做。如果輸入了,則用e l i f測試是否匹配r o o t、l o u i s e或d a v e,如果不匹配其
中任何一個,則打印該名字,通知用戶不是r o o t、l o u i s e或d a v e。
  1. #!/bin/sh
  2. # ifelif.sh
  3. echo  -n "enter your login name :"
  4. read NAME
  5. # no name entered do not carry on
  6. if [ -z $NAME ] || [ "$NAME" == "" ]; then
  7.         echo "You did not enter a name"
  8. elif   
  9.         # is the name root
  10.         [ "$NAME" == "root" ]; then
  11.         echo "Hello root"
  12. elif   
  13.         # or is it louise
  14.         [ $NAME == "louise" ]; then
  15.         echo "Hello louise"
  16. elif   
  17.         # or is it dave
  18.         [ "$NAME" == "dave" ]; then
  19.         echo "Hello dave"
  20. else   
  21.         # no it's somebody else
  22.         echo "You are not root or louise or dave but hi $NAME"
  23. fi
  24. 運行上述腳本,給出不同信息,得結(jié)果如下:                              
  25. [root@localhost ~]# chmod +x ifelif.sh
  26. [root@localhost ~]# ./ifelif.sh
  27. enter your login name :dave
  28. Hello dave
  29. [root@localhost ~]# ./ifelif.sh
  30. enter your login name :
  31. You did not enter a name
  32. [root@localhost ~]# ./ifelif.sh
  33. enter your login name :Peter
  34. You are not root or louise or dave but hi Peter
復(fù)制代碼
多文件位置檢測
假定要定位一個用戶登錄文件,已知此文件在/ u s r / o p t s / a u d i t / l o g s或/ u s r / l o c a l / a u d i t / l o g s中,
具體由其安裝人決定。在定位此文件前,首先確保文件可讀,此即腳本測試部分。如果未找
到文件或文件不可讀,則返回錯誤信息。腳本如下:
  1. #!/bin/sh
  2. # ifcataudit.sh
  3. # locations of the log file
  4. LOCAT_1=/usr/opts/audit/logs/audit.log
  5. LOCAT_2=/usr/local/audit/audit.logs
  6. if [ -r $LOCAT_1 ]; then
  7.         # if it is in this directory and is readable then cat is
  8.         echo "Using LOCAT_1"
  9.         cat $LOCAT_1
  10. elif   
  11.         # else it then must be in this direcotory, and is it readable
  12.         [ -r $LOCAT_2 ]
  13. then   
  14.         echo "Using LOCAT_2"
  15.         cat $LOCAT_2
  16. else   
  17.         # not in any of the directories...
  18.         echo "`basename $0`: Sorry the audit file is not readable or cannot be
  19.         localted." >&2
  20.         exit 1
  21. fi      
復(fù)制代碼
運行上面腳本,如果文件在上述兩個目錄之一中并且可讀,將可以找到它。如果不是,
返回錯誤并退出,下面結(jié)果失敗,因為假想的文件并不存在
  1. [root@localhost ~]# ./ifcataudit.sh
  2. ifcataudit.sh: Sorry the audit file is not readable or cannot be
  3.                 localted.
復(fù)制代碼

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
6 [報告]
發(fā)表于 2010-11-20 19:24 |只看該作者
提示鍵入y或n
c a s e的一個有效用法是提示用戶響應(yīng)以決定是否繼續(xù)進(jìn)程。這里提示輸入y以繼續(xù)處理,n
退出。如果用戶輸入Y、y或y e s,處理繼續(xù)執(zhí)行c a s e語句后面部分。如果用戶輸入N、n或n o或
其他響應(yīng),用戶退出腳本。
  1. #!/bin/sh
  2. # caseans.sh
  3. echo -n "Do you wish to proceed [y..n] :"
  4. read ANS
  5. case $ANS in
  6.         y|Y|yes|Yes) echo "yes is selected"
  7.         ;;
  8.         n|N) echo "no is selected"
  9.         exit 0  # no error so only use exit 0 to terminate
  10.         ;;
  11.         *) echo "`basename $0` : Unknow response" >&2
  12.         exit 1
  13.         ;;
  14. esac   
  15. # if we are here then a y|Y|yes|Yes was selected only.
復(fù)制代碼
運行腳本,輸入無效響應(yīng),得結(jié)果:
  1. [root@localhost ~]# ./caseans.sh
  2. Do you wish to proceed [y..n] :df
  3. caseans.sh : Unknow response
復(fù)制代碼
給出有效響應(yīng):
  1. [root@localhost ~]# ./caseans.sh
  2. Do you wish to proceed [y..n] :y
  3. yes is selected
復(fù)制代碼
case與命令參數(shù)傳遞
可以使用c a s e控制到腳本的參數(shù)傳遞。
下面腳本中,測試特定變量$ #,它包含傳遞的參數(shù)個數(shù),如果不等于1,退出并顯示可用
信息。
然后c a s e語句捕獲下列參數(shù): p a s s w d、s t a r t、s t o p或h e l p,相對于每一種匹配模式執(zhí)行進(jìn)
一步處理腳本。如果均不匹配,顯示可用信息到標(biāo)準(zhǔn)錯誤輸出。

  1. #!/bin/sh
  2. # caseparam.sh
  3. if [ $# != 1 ]; then
  4.         echo "Usage:`basename $0`[start|stop|help]" >&2
  5.         exit 1
  6. fi      
  7. # assign the parameter to the variable OPT
  8. OPT=$1
  9. case $OPT in
  10.         start) echo "starting.. `basename $0`"
  11.         # code here to start a process
  12.         ;;
  13.         stop) echo "stopping.. `basename $0`"
  14.         # code here to stop a process
  15.         ;;
  16.         help)
  17.         # code here to display a help page
  18.         ;;
  19.         *) echo "Usage:`basename $0`[start|stop|help]"
  20.         ;;
  21. esac   
復(fù)制代碼
運行腳本,輸入無效參數(shù)。
  1. [root@localhost ~]# ./caseparam.sh what
  2. Usage:caseparam.sh[start|stop|help]
復(fù)制代碼
輸入有效參數(shù),結(jié)果為:
  1. [root@localhost ~]# ./caseparam.sh stop
  2. stopping.. caseparam.sh
復(fù)制代碼
捕獲輸入并執(zhí)行空命令
不一定要在匹配模式后加入命令,如果你原本不想做什么,只是在進(jìn)一步處理前過濾出
意外響應(yīng),這樣做是一種好辦法。
如果要運行對應(yīng)于一個會計部門的帳目報表,必須首先在決定運行報表的類型前確認(rèn)用
戶輸入一個有效的部門號,匹配所有可能值,其他值無效。用c a s e可以很容易實現(xiàn)上述功能。
下面的腳本中如果用戶輸入部門號不是2 3 4、4 5 3、6 5 5或4 5 4,用戶退出并返回可用信息。
一旦響應(yīng)了用戶的有效部門號,腳本應(yīng)用同樣的技術(shù)取得報表類型,在c a s e語句末尾顯示有
效的部門號和報表類型。腳本如下:
  1. #!/bin/sh
  2. # casevaild.sh
  3. echo -n "Enter the account dept No: :"
  4. read ACC
  5. case $ACC in
  6.         234);;
  7.         453);;
  8.         655);;
  9.         454);;
  10.         *) echo "`basename $0`: Unknown dept No:" >&2
  11.         echo "try ... 234,453,655,454"
  12.         exit 1
  13.         ;;
  14. esac
  15. # if we are here, then we have validated the dept no
  16. echo "1 . post"
  17. echo "2 . prior"
  18. echo -n "Enter the type of report:"
  19. read ACC_TYPE
  20. case $ACC_TYPE in
  21.         1) TYPE=post
  22.         ;;
  23.         2) TYPE=prior;;
  24.         *) echo "`basename $0`: Unknown account type." >&2
  25.         exit 1
  26.         ;;
  27. esac
  28. # if we are here the we are validated!
  29. echo "now running report for dept $ACC for the type $TYPE"
  30. # run the command reprot...
復(fù)制代碼
下面是該腳本不同運行輸入情況的顯示結(jié)果。
輸入有效部門號:
  1. [root@localhost ~]# ./casevalid.sh
  2. Enter the account dept No: :234
  3. 1 . post
  4. 2 . prior
  5. Enter the type of report:2
  6. now running report for dept 234 for the type prior
復(fù)制代碼
輸入無效部門號:
  1. [root@localhost ~]# ./casevalid.sh
  2. Enter the account dept No: :432
  3. casevalid.sh: Unknown dept No:
  4. try ... 234,453,655,454
復(fù)制代碼
輸入無效的報表類型:
  1. [root@localhost ~]# ./casevalid.sh
  2. Enter the account dept No: :655
  3. 1 . post
  4. 2 . prior
  5. Enter the type of report:4
  6. casevalid.sh: Unknown account type.
復(fù)制代碼
缺省變量值
如果在讀變量時輸入回車鍵,不一定總是退出腳本。可以先測試是否已設(shè)置了變量,如
果未設(shè)置,可以設(shè)置該值。
下面的腳本中,要求用戶輸入運行報表日期。如果用戶輸入回車鍵,則使用缺省日期星
期六,并設(shè)置為變量w h e n的取值。
如果用戶輸入另外一天,這一天對于c a s e語句是運行的有效日期,即星期六、星期四、星
期一。注意,這里結(jié)合使用了日期縮寫作為捕獲的可能有效日期。
腳本如下:
  1. #!/bin/sh
  2. # caserep.sh
  3. echo "      Weekly Report"
  4. echo -n "What day do you want to run report [Saturday] :"
  5. # if just a return is hit then except default which is Saturday
  6. read WHEN
  7. echo "validating .. ${WHEN:="Saturday"}"
  8. case $WHEN in
  9.         Monday|MONDAY|mon)
  10.         ;;
  11.         Sunday|SUNDAY|sun)
  12.         ;;
  13.         Saturday|SATURDAY|sat)
  14.         ;;
  15.         *)
  16.         echo "Are you nuts! this report can only be run on " >&2
  17.         echo " on a Saturday, Sunday or Monday" >&2
  18.         exit 1
  19.         ;;
  20. esac   
  21. echo "Report to run on $WHEN"
  22. # command here to submitted actual report run
復(fù)制代碼
對于正確輸入:
  1. [root@localhost ~]# ./caserep.sh
  2.                 Weekly Report
  3. What day do you want to run report [Saturday] :
  4. validating .. Saturday
  5. Report to run on Saturday
復(fù)制代碼
對于錯誤的輸入:
  1. [root@localhost ~]# ./caserep.sh
  2.                 Weekly Report
  3. What day do you want to run report [Saturday] :Tuesday
  4. validating .. Tuesday
  5. Are you nuts! this report can only be run on
  6. on a Saturday, Sunday or Monday
復(fù)制代碼
可以推斷出c a s e語句有時與if then else 語句功能相同,在某些條件下,這種假定是正確
的。

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
7 [報告]
發(fā)表于 2010-11-20 20:19 |只看該作者
f o r循環(huán)一般格式為:
for 變量名i n列表
d o
命令1
命令2⋯
d o n e

當(dāng)變量值在列表里, f o r循環(huán)即執(zhí)行一次所有命令,使用變量名訪問列表中取值。命令可
為任何有效的s h e l l命令和語句。變量名為任何單詞。I n列表用法是可選的,如果不用它, f o r
循環(huán)使用命令行的位置參數(shù)。
i n列表可以包含替換、字符串和文件名,下面看一些例子。

還有一種常見的for循環(huán)的格式是:
for ((初值; 循環(huán)條件; 執(zhí)行步長))
do
            執(zhí)行的程序段
done
也就是括號中的內(nèi)容是平常我們熟悉的C語言的風(fēng)格。


簡單的for循環(huán)
此例僅顯示列表1 2 3 4 5,用變量名訪問列表。
  1. #!/bin/sh
  2. # for_i.sh
  3. for loop in 1 2 3 4 5
  4. do
  5.         echo $loop
  6. done
復(fù)制代碼
運行上述腳本,輸出:
  1. [root@localhost ~]# ./for_i.sh
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
復(fù)制代碼
上面中的1 2 3 4 5序列也可以用下面的方式生成。seq 5或者echo {1..5}的方式。


打印字符串列表
下面f o r循環(huán)中,列表包含字符串“ orange red blue grey”,命令為e c h o,變量名為l o o p,
e c h o命令使用$ l o o p反饋出列表中所有取值,直至列表為空。
  1. #!/bin/sh
  2. # forlist.sh
  3. for loop in "orange red blue grey"
  4. do
  5.         echo "$loop"
  6. done
復(fù)制代碼
運行腳本輸出內(nèi)容是:
orange red blue grey
也可以在循環(huán)體中結(jié)合使用變量名和字符串。
This is the fruit $loop
其輸出結(jié)果是:
This is the fruit orange red blue grey
對for循環(huán)使用ls命令
這個循環(huán)執(zhí)行l(wèi) s命令,打印當(dāng)前目錄下所有文件。
  1. #!/bin/sh
  2. # forls.sh
  3. for loop in `ls `
  4. do
  5.         echo $loop
  6. done
復(fù)制代碼
對for循環(huán)使用參數(shù)
在f o r循環(huán)中省去i n列表選項時,它將接受命令行位置參數(shù)作為參數(shù)。實際上即指明:
for params in"$@"

for params in"$*"
下面的例子不使用i n列表選項, f o r循環(huán)查看特定參數(shù)$ @或$ *,以從命令行中取得參數(shù)。
  1. #!/bin/sh
  2. # forparam2
  3. for params
  4. do
  5.         echo "You supplied $params as a command line option"
  6. done
復(fù)制代碼
下面的腳本包含i n"$ @",結(jié)果與上面的腳本相同。
  1. #!/bin/sh
  2. # forparam3
  3. for params in "$@"
  4. do
  5.         echo "You supplied $params as a command line option"
  6. done
復(fù)制代碼
對上述腳本采取進(jìn)一步動作。如果要查看一系列文件,可在f o r循環(huán)里使用f i n d命令,利
用命令行參數(shù),傳遞所有要查閱的文件。
  1. #!/bin/sh
  2. # forfind.sh
  3. for loop
  4. do
  5.         find / -name $loop -print
  6. done
復(fù)制代碼
腳本執(zhí)行時,從命令行參數(shù)中取值并使用f i n d命令,這些取值形成- n a m e選項的參數(shù)值。

使用for循環(huán)連接服務(wù)器
因為f o r循環(huán)可以處理列表中的取值,現(xiàn)設(shè)變量為網(wǎng)絡(luò)服務(wù)器名稱,并使用f o r循環(huán)連接每
一服務(wù)器。
  1. #!/bin/sh
  2. # forping.sh
  3. HOSTS="itserv dnssevr acctsmain ladpd ladwareA"
  4. for loop in $HOSTS
  5. do
  6.         ping -c 2 $loop
  7. done
復(fù)制代碼
使用for循環(huán)備份文件
可以用f o r循環(huán)備份所有文件,只需將變量作為c p命令的目標(biāo)參數(shù)。這里有一變量. b a k,
當(dāng)在循環(huán)中使用c p命令時,它作為此命令目標(biāo)文件名。列表命令為l s。
  1. #!/bin/sh
  2. # forbak.sh
  3. suffix=".bak"
  4. for loop in `ls `
  5. do
  6.         cp $loop $loop$suffix
  7. done
復(fù)制代碼
多文件轉(zhuǎn)換
匹配所有以L P S O開頭文件并將其轉(zhuǎn)換為大寫。這里使用了l s和c a t命令。l s用于查詢出相
關(guān)文件, c a t用于將之管道輸出至t r命令。目標(biāo)文件擴(kuò)展名為.U C,注意在f o r循環(huán)中使用l s命令
時反引號的用法。
  1. #!/bin/sh
  2. # forUC.sh
  3. for files in `ls LPSO*`
  4. do
  5.         cat $files | tr "[a-z]" "[A-Z]" > $file.UC
  6. done
復(fù)制代碼
多sed刪除操作
下面的例子中, s e d用于刪除所有空文件,并將輸出導(dǎo)至以. H O L D . m v為擴(kuò)展名的新文件
中,m v將這些文件移至初始文件中。
  1. #!/bin/sh
  2. # forsed.sh
  3. for files in `ls LPSO*`
  4. do
  5.         sed -e "/^$/d" $files >$files.HOLD
  6.         mv $files.HOLD $files
  7. done
復(fù)制代碼
循環(huán)計數(shù)
前面討論e x p r時指出,循環(huán)時如果要加入計數(shù),使用此命令。下面使用l s在f o r循環(huán)中列出
文件及其數(shù)目。
  1. #!/bin/sh
  2. # forcount.sh
  3. counter=0
  4. for files in *
  5. do
  6.         # increment
  7.         counter=`expr $counter + 1`
  8. done
  9. echo "There are $counter files in `pwd` we need to process"
復(fù)制代碼
腳本的輸出結(jié)果是:
There are 87 files in /root we need to process
使用w c命令可得相同結(jié)果。
[root@localhost ~]# ls | wc -l
87

for循環(huán)和本地文檔
在f o r循環(huán)體中可使用任意命令。下面的例子中,一個變量包含所有當(dāng)前登錄用戶。使用
w h o命令并結(jié)合a w k語言可實現(xiàn)此功能。然后f o r循環(huán)循環(huán)每一用戶,給其發(fā)送一個郵件,郵件
信息部分用一個本地文檔完成。
  1. #!/bin/sh
  2. # formailit.sh
  3. WHOS_ON=`who -u | awk '{print $1}'`
  4. for user in $WHOS_ON
  5. do
  6.         mail $user << MAYDAY
  7.         Dear Colleagues,
  8.         It's my birthday today, see you down the
  9.         club at 17:30 for a drink.

  10.         See ya.
  11.         $LOGNAME
  12.         MAYDAY
  13.         Done
復(fù)制代碼
這個例子無法實現(xiàn),可能原書上有錯誤,或者翻譯有錯誤。


for循環(huán)嵌入
嵌入循環(huán)可以將一個f o r循環(huán)嵌在另一個f o r循環(huán)內(nèi):
for 變量名1 in列表1
d o
for 變量名2 in 列表2
d o
命令1
. . .
d o n e
d o n e
下面腳本即為嵌入f o r循環(huán),這里有兩個列表A P P S和S C R I P T S。第一個包含服務(wù)器上應(yīng)用
的路徑,第二個為運行在每個應(yīng)用上的管理腳本。對列表A P P S上的每一個應(yīng)用,列表
S C R I P T S里的腳本將被運行,腳本實際上為后臺運行。腳本使用t e e命令在登錄文件上放一條
目,因此輸出到屏幕的同時也輸出到一個文件。查看輸出結(jié)果就可以看出嵌入f o r循環(huán)怎樣使
用列表S C R I P T S以執(zhí)行列表A P P S上的處理。
  1. #!/bin/sh
  2. # audit_run.sh
  3. APPS="/apps/accts /apps/claims /apps/stock /apps/serv"
  4. SCRIPTS="audit.check report.run cleanup"
  5. LOGFILE=audit.log
  6. MY_DATE=`date +%H:%M" on "%d/%m%Y`
  7. # outer loop
  8. for loop in $APPS
  9. do      
  10.         # inner loop
  11.         for loop2 in $SCRIPTS
  12.         do      
  13.                 echo "system $loop now running $loop2 at $MY_DATE" | tee -a\
  14.                  $LOGFILE $loop $loop2 &
  15.          done   
  16. done   
復(fù)制代碼
程序的運行結(jié)果如下:
  1. tee: /apps/accts: No such file or directory
  2. tee: /apps/accts: No such file or directory
  3. system /apps/accts now running report.run at 20:18 on 21/112010
  4. tee: /apps/accts: No such file or directory
  5. system /apps/accts now running cleanup at 20:18 on 21/112010
  6. tee: /apps/claims: No such file or directory
  7. system /apps/claims now running audit.check at 20:18 on 21/112010
  8. tee: /apps/claims: No such file or directory
  9. system /apps/claims now running report.run at 20:18 on 21/112010
  10. tee: /apps/claims: No such file or directory
  11. system /apps/claims now running cleanup at 20:18 on 21/112010
  12. tee: /apps/stock: No such file or directory
  13. system /apps/stock now running audit.check at 20:18 on 21/112010
  14. tee: /apps/stock: No such file or directory
  15. system /apps/stock now running report.run at 20:18 on 21/112010
  16. tee: /apps/stock: No such file or directory
  17. system /apps/stock now running cleanup at 20:18 on 21/112010
  18. tee: /apps/serv: No such file or directory
  19. system /apps/serv now running audit.check at 20:18 on 21/112010
  20. [root@localhost ~]# system /apps/accts now running audit.check at 20:18 on 21/112010
  21. tee: /apps/serv: No such file or directory
  22. system /apps/serv now running report.run at 20:18 on 21/112010
  23. tee: /apps/serv: No such file or directory
  24. system /apps/serv now running cleanup at 20:18 on 21/112010
復(fù)制代碼

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
8 [報告]
發(fā)表于 2010-11-20 20:27 |只看該作者
until循環(huán)
u n t i l循環(huán)執(zhí)行一系列命令直至條件為真時停止。u n t i l循環(huán)與w h i l e循環(huán)在處理方式上剛好
相反。一般w h i l e循環(huán)優(yōu)于u n t i l循環(huán),但在某些時候—也只是極少數(shù)情況下, u n t i l循環(huán)更加
有用。
u n t i l循環(huán)格式為:
until 條件
命令1
. . .
d o n e
條件可為任意測試條件,測試發(fā)生在循環(huán)末尾,因此循環(huán)至少執(zhí)行一次—請注意這一
點。
下面是一些實例。
簡單的until循環(huán)
這段腳本不斷的搜尋w h o命令中用戶r o o t,變量I S - R O O T保存g r e p命令結(jié)果。
如果找到了r o o t,循環(huán)結(jié)束,并向用戶s i m o n發(fā)送郵件,通知他用戶r o o t已經(jīng)登錄,注意
這里s l e e p命令用法,它經(jīng)常用于u n t i l循環(huán)中,因為必須讓循環(huán)體內(nèi)命令睡眠幾秒鐘再執(zhí)行,
否則會消耗大量系統(tǒng)資源。
  1. #!/bin/sh
  2. # until_who.sh
  3. IS_ROOT=`who | grep root`
  4. until [ "$IS_ROOT" ]
  5. do
  6.         sleep 5
  7. done   
  8. echo "Watch it. roots in " | mail simon
復(fù)制代碼
監(jiān)視文件
下面例子中, u n t i l循環(huán)不斷掛起做睡眠,直至文件/ t m p / m o n i t o r. l c k被刪除。文件刪除后,
腳本進(jìn)入正常處理過程。
  1. #!/bin/sh
  2. # until_lck.sh
  3. LOCK_FILE=/tmp/process.LCK
  4. until [ ! -f $LOCK_FILE ]
  5. do
  6.         sleep 1
  7. done   
  8. echo "file deleted "
  9. # normal processing now, file is present
復(fù)制代碼
上述例子是使腳本與其他處理過程協(xié)調(diào)工作的一種方法。還有另外一種方法使腳本間互
相通信。假定有另一段腳本p r o c e s s . m a i n用于搜集本地網(wǎng)絡(luò)所有機(jī)器的信息并將之放入一個報
表文件。
當(dāng)腳本p r o c e s s . m a i n運行時,創(chuàng)建了一個L C K文件(鎖文件),上面腳本必須接收
p r o c e s s . m a i n搜集的信息,但是如果p r o c e s s仍然在修改報表文件時試圖處理該文件就不太好
了。
為克服這些問題,腳本p r o c e s s . m a i n創(chuàng)建了一個L C K文件,當(dāng)它完成時,就刪除此文件。
上述腳本將掛起,等待L C K文件被刪除,一旦L C K文件刪除,上述腳本即可處理報表文
件。

監(jiān)視磁盤空間
u n t i l循環(huán)做監(jiān)視條件也很有用。假定要監(jiān)視文件系統(tǒng)容量,當(dāng)它達(dá)到一定水平時通知超
級用戶。
下面的腳本監(jiān)視文件系統(tǒng)/ l o g s,不斷從變量$L O O K_O U T中抽取信息, $ L O O K _ O U T包
含使用a w k和g r e p得到的/ l o g s容量。
如果容量達(dá)到9 0 %,觸發(fā)命令部分,向超級用戶發(fā)送郵件,腳本退出。必須退出,如果
不退出,條件保持為真(例如,容量總是保持在9 0 %以上),將會不斷的向超級用戶發(fā)送郵
件。
  1. #!/bin/sh
  2. # until_mon.sh
  3. # get present column and strip off header row from df
  4. LOOK_OUT=`df | grep /logs | awk '{print $5}' | sed 's/%//g'`
  5. echo $LOOK_OUT
  6. until [ "$LOOK_OUT -gt "90" ]
  7. do
  8.         echo "Filesystem..logs is nearly full" | mail root
  9.         exit 0
  10. done
復(fù)制代碼

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
9 [報告]
發(fā)表于 2010-11-20 21:24 |只看該作者
while循環(huán)
w h i l e循環(huán)用于不斷執(zhí)行一系列命令,也用于從輸入文件中讀取數(shù)據(jù),其格式為:
while 命令
d o
命令1
命令2
. . .
d o n e
雖然通常只使用一個命令,但在w h i l e和d o之間可以放幾個命令。命令通常用作測試條
件。
只有當(dāng)命令的退出狀態(tài)為0時,d o和d o n e之間命令才被執(zhí)行,如果退出狀態(tài)不是0,則循
環(huán)終止。
命令執(zhí)行完畢,控制返回循環(huán)頂部,從頭開始直至測試條件為假。

簡單的while循環(huán)
以下是一個基本的w h i l e循環(huán),測試條件是:如果C O U N T E R小于5,那么條件返回真。
C O U N T E R從0開始,每次循環(huán)處理時, C O U N T E R加1。
  1. #!/bin/sh
  2. # whilecount.sh
  3. COUNTER=0
  4. # does the counter = 5 ?
  5. while [ $COUNTER -lt 5 ]
  6. do
  7.         # add ono to the counter
  8.         COUNTER=`expr $COUNTER + 1`
  9.         echo $COUNTER
  10. done
復(fù)制代碼
運行上述腳本,返回數(shù)字1到5,然后終止。

使用while循環(huán)讀鍵盤輸入
w h i l e循環(huán)可用于讀取鍵盤信息。下面的例子中,輸入信息被設(shè)置為變量F I L M,按< C t r l -
D >結(jié)束循環(huán)。
  1. #!/bin/sh
  2. # whileread.sh
  3. echo "type <CTRL-D> to terminate"
  4. echo -n "Enter your most liked file :"
  5. while read FILE
  6. do
  7.         echo "Yeah, great film the $FILE"
  8. done
復(fù)制代碼
程序的運行結(jié)果如下:
type <CTRL-D> to terminate
Enter your most liked file :Sound of Music
Yeah, great film the Sound of Music
<CTRL-D>

用while循環(huán)從文件中讀取數(shù)據(jù)
w h i l e循環(huán)最常用于從一個文件中讀取數(shù)據(jù),因此編寫腳本可以處理這樣的信息。
假定要從下面包含雇員名字、從屬部門及其I D號的一個文件中讀取信息。names.txt
Louise Conrad:Accounts:ACC8987
Peter JamesayrollR489
Fred Terms:Customer:CUS012
James Lenod:Accounts:ACC887
Frank PavelyayrollR489

可以用一個變量保存每行數(shù)據(jù),當(dāng)不再有讀取數(shù)據(jù)時條件為真。w h i l e循環(huán)使用輸入重定
向以保證從文件中讀取數(shù)據(jù)。注意整行數(shù)據(jù)被設(shè)置為單變量$ L I N E .。
  1. #!/bin/sh
  2. # whileread.sh
  3. while read LINE
  4. do
  5.         echo $LINE
  6. done < names.txt
復(fù)制代碼
程序的運行結(jié)果如下:
  1. [root@localhost ~]# ./whileread.sh
  2. Louise Conrad:Accounts:ACC8987
  3. Peter James:Payroll:PR489
  4. Fred Terms:Customer:CUS012
  5. James Lenod:Accounts:ACC887
  6. Frank Pavely:Payroll:PR489
復(fù)制代碼
使用IFS讀文件
輸出時要去除冒號域分隔符,可使用變量I F S。在改變它之前保存I F S的當(dāng)前設(shè)置。然后
在腳本執(zhí)行完后恢復(fù)此設(shè)置。使用I F S可以將域分隔符改為冒號而不是空格或t a b鍵。這里有3
個域需要加域分隔,即N A M E、D E P T和I D。
為使輸出看起來更清晰,對e c h o命令使用t a b鍵將域分隔得更開一些,腳本如下:
  1. #!/bin/sh
  2. # whilereadifs
  3. # save the setting of IFS
  4. SAVEDIFS=$IFS
  5. # assign new separator to IFS
  6. IFS=:
  7. while read NAME DEPT ID
  8. do
  9.         echo -e "$NAME\t $DEPT\t $ID"
  10. done < names.txt
  11. # restore the settings of IFS
  12. IFS=$SAVEDIFS
復(fù)制代碼
腳本運行后的輸出結(jié)果如下,結(jié)果清晰多了。
Louise Conrad    Accounts        ACC8987
Peter James      Payroll         PR489
Fred Terms       Customer        CUS012
James Lenod      Accounts        ACC887
Frank Pavely     Payroll         PR489


帶有測試條件的文件處理
大部分w h i l e循環(huán)里都帶有一些測試語句,以決定下一步的動作。
這里從人員文件中讀取數(shù)據(jù),打印所有細(xì)節(jié)到一個保留文件中,直至發(fā)現(xiàn)James Lenod,
腳本退出。測試前反饋的信息要確! James Lenod”加入保留文件中。
注意,所有變量在腳本頂端被設(shè)置完畢。這樣當(dāng)不得不對變量進(jìn)行改動時可以節(jié)省時間
和輸入。所有編輯都放在腳本頂端,而不是混于整個腳本間。
  1. #!/bin/sh
  2. # whileread_file.sh
  3. # initialise variables
  4. SAVEDIFS=$IFS
  5. IFS=:
  6. HOLD_FILE=hold_file
  7. NAME_MATCH="James Lenod"
  8. INPUT_FILE=names.txt

  9. # create a new HOLD_FILE each time, in case script is continuously run
  10. >$HOLD_FILE
  11. while read NAME DEPT ID
  12. do
  13.         # echo all information into holdfile with redirection
  14.         echo $NAME $DEPT $ID >> $HOLD_FILE
  15.         # is it a match ???
  16.         if [ "$NAME" == "$NAME_MATCH" ]; then
  17.                 # yes then nice exit
  18.                 echo "all entries up to and including $NAME_MATCH are in $HOLD_F
  19. ILE"
  20.                 exit 0
  21.         fi      
  22. done < $INPUT_FILE
  23. # restore IFS
  24. IFS=$SAVEDIFS
復(fù)制代碼
還可以采取進(jìn)一步動作,列出多少個雇員屬于同一部門。這里保持同樣的讀方式。假定
每個域都有一個變量名,然后在c a s e語句里用e x p r增加每行匹配腳本。任何發(fā)現(xiàn)的未知部門
知識反饋到標(biāo)準(zhǔn)錯誤中,如果一個無效部門出現(xiàn),沒有必要退出。
  1. #!/bin/sh
  2. # whileread_cond.sh
  3. # initialise variables
  4. ACC_LOOP=0; CUS_LOOP=0; PAY_LOOP=0;
  5. SAVEDIFS=$IFS
  6. IFS=:
  7. while read NAME DEPT ID
  8. do
  9.         # increment counter for each matched dept.
  10.         case $DEPT in
  11.                 Accounts) ACC_LOOP=`expr $ACC_LOOP + 1`
  12.                 ACC="Accounts"
  13.                 ;;
  14.                 Customer) CUS_LOOP=`expr $CUS_LOOP + 1`
  15.                 CUS="Customer"
  16.                 ;;
  17.                 Payroll) PAY_LOOP=`expr $PAY_LOOP + 1`
  18.                 PAY="Payroll"
  19.                 ;;
  20.                 *) echo "`basename $0`: Unknown department $DEPT" >&2
  21.                 ;;
  22.         esac
  23. done < names.txt
  24. IFS=$SAVEDIFS
  25. echo "there are $ACC_LOOP employees assigned to $ACC dept"
  26. echo "there are $CUS_LOOP employees assigned to $CUS dept"
  27. echo "there are $PAY_LOOP employees assigned to $PAY dept"
復(fù)制代碼
程序運行的結(jié)果如下所示:
  1. [root@localhost ~]# ./whileread_cond.sh   
  2. there are 2 employees assigned to Accounts dept
  3. there are 1 employees assigned to Customer dept
  4. there are 2 employees assigned to Payroll dept
  5. [root@localhost ~]# vim whileread_cond.sh
復(fù)制代碼
掃描文件行來進(jìn)行數(shù)目統(tǒng)計
一個常用的任務(wù)是讀一個文件,統(tǒng)計包含某些數(shù)值列的數(shù)值總和。下面的文件包含有部
門S TAT和G I F T所賣的商品數(shù)量。
  1. [root@localhost ~]# cat total.txt
  2. STAT    3444
  3. GIFT     233
  4. GIFT     252
  5. GIFT     932
  6. STAT     212
  7. STAT     923
  8. GIFT     129
復(fù)制代碼
現(xiàn)在的任務(wù)是要統(tǒng)計部門G I F T所賣的各種商品數(shù)量。使用e x p r保存統(tǒng)計和,看下面的
e x p r語句。變量L O O P和TO TA L首先在循環(huán)外初始化為0,循環(huán)開始后, I T E M S加入TO TA L,
第一次循環(huán)只包含第一種商品,但隨著過程繼續(xù), I T E M S逐漸加入TO TA L。
下面的e x p r語句不斷增加計數(shù)。
LOOP=0
TOTAL=0
...
while ...
do
TOTAL=`expr $TOTAL + $ITEMS`
ITEMS=`expr $ITEMS + 1`
done

使用e x p r語句時容易犯的一個錯誤是開始忘記初始化變量。
LOOP=0
TOTAL=0
如果真的忘了初始化,屏幕上將布滿e x p r錯誤。
如果愿意,可以在循環(huán)內(nèi)初始化循環(huán)變量。
TOTAL=`expr ${TOAL:=0} + ${ITEMS}`
上面一行如果變量TO TA L未賦值,將其初始化為0。這是在e x p r里初始化變量的第一個例
子。另外在循環(huán)外要打印出最后總數(shù)。
  1. #!/bin/sh
  2. # total.sh
  3. # init variables
  4. LOOP=0
  5. TOTAL=0
  6. COUNT=0
  7. echo "Items Dept"
  8. echo "____________"
  9. while read DEPT ITEMS
  10. do
  11.         # keep a count on total records read
  12.         COUNT=`expr $COUNT + 1`
  13.         if [ "$DEPT" == "GIFT" ]; then
  14.                 # keep a running total
  15.                 TOTAL=`expr $TOTAL + $ITEMS`
  16.                 ITEMS=`expr $ITEMS + 1`
  17.                 echo -e "$ITEMS\t$DEPT"
  18.         fi      
  19.         # echo $DEPT $ITEMS
  20. done < total.txt
  21. echo "============"
  22. echo $TOTAL
  23. echo "There were $COUNT entries altogether in the file"
復(fù)制代碼
腳本的運行結(jié)果如下所示:
  1. Items Dept
  2. ____________
  3. 234     GIFT
  4. 253     GIFT
  5. 933     GIFT
  6. 130     GIFT
  7. ============
  8. 1546
  9. There were 7 entries altogether in the file
復(fù)制代碼
每次讀一對記錄
有時可能希望每次處理兩個記錄,也許可從記錄中進(jìn)行不同域的比較。每次讀兩個記錄
很容易,就是要在第一個w h i l e語句之后將第二個讀語句放在其后。使用這項技術(shù)時,不要忘
了不斷進(jìn)行檢查,因為它實際上讀了大量的記錄。
[root@localhost ~]# cat record.txt
record 1
record 2
record 3
record 4
record 5
record 6
每次讀兩個記錄,下面的例子對記錄并不做實際測試。
腳本如下:
  1. #!/bin/sh
  2. # readpair.sh
  3. # first record
  4. while read rec1
  5. do
  6.         # second record
  7.         read rec2
  8.         # further processing/testing goes here to test or compare both records
  9.         echo "This is record on of a pair :$rec1"
  10.         echo "This is record on of a pair :$rec2"
  11.         echo "----------------------------"
  12. done < record.txt
復(fù)制代碼
首先來檢查確實讀了很多記錄,可以使用w c命令:
[root@localhost ~]# cat record.txt | wc -l
6
共有6個記錄,觀察其輸出:
This is record on of a pair :record 1
This is record on of a pair :record 2
----------------------------
This is record on of a pair :record 3
This is record on of a pair :record 4
----------------------------
This is record on of a pair :record 5
This is record on of a pair :record 6
----------------------------

忽略#字符
讀文本文件時,可能要忽略或丟棄遇到的注釋行,下面是一個典型的例子。
假定要使用一般的w h i l e循環(huán)讀一個配置文件,可揀選每一行,大部分都是實際操作語句。
有時必須忽略以一定字符開頭的行,這時需要用c a s e語句,因為#是一個特殊字符,最好首先
用反斜線屏蔽其特殊意義,在#符號后放一個星號*,指定*后可包含任意字符。
配置文件如下:
  1. [root@localhost ~]# cat config
  2. # THIS IS THE SUB SYSTEM AUDIT CONFIG FILE
  3. # DO NOT EDIT!!!!.IT WORKS
  4. #
  5. # type of admin access
  6. AUDITSCH=full
  7. # lanuch place of sub-systems
  8. AUDITSUB=/usr/opt/audit/sub
  9. # serial hash number of product
  10. HASHSER=12890AB3
  11. # END OF CONFIG FILE!!!
復(fù)制代碼
忽略#符號的實現(xiàn)腳本如下:
  1. #!/bin/sh
  2. # ignore_hash.sh
  3. INPUT_FILE=config
  4. if [ -s $INPUT_FILE ]; then
  5.         while read LINE
  6.         do      
  7.                 case $LINE in
  8.                         \#*);;
  9.                         # ignore any hash signs
  10.                         *) echo $LINE
  11.                         ;;
  12.                 esac   
  13.         done < $INPUT_FILE
  14. else   
  15.         echo "`basename $0` : Sorry $INPUT_FILE does not exist or is empty"
  16.         exit 1
  17. fi      
復(fù)制代碼
程序的輸出結(jié)果如下:
AUDITSCH=full
AUDITSUB=/usr/opt/audit/sub
HASHSER=12890AB3

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
10 [報告]
發(fā)表于 2010-11-20 21:59 |只看該作者
處理格式化報表
讀報表文件時,一個常用任務(wù)是將不想要的行剔除。以下是庫存商品水平列表,我們感
興趣的是那些包含商品記錄當(dāng)前水平的列
  1. [root@localhost ~]# cat order
  2. ################ RE-ORDER REPORT  ##############
  3. ITEM           ORDERLEVEL              LEVEL
  4. ####################################################
  5. Pens            14                              12
  6. Pencils         15                              15
  7. Pads             7                               3
  8. Disks            3                               2
  9. Sharpeners       5                               1
  10. ####################################################
復(fù)制代碼
我們的任務(wù)是讀取其中取值,決定哪些商品應(yīng)重排。如果重排,重排水平應(yīng)為現(xiàn)在商品
的兩倍。輸出應(yīng)打印需要重排的每種商品數(shù)量及重排總數(shù)。
我們已經(jīng)知道可以忽略以某些字符開始的行,因此這里沒有問題。首先讀文件,忽略所
有注釋行和以‘ I T E M’開始的標(biāo)注行。讀取文件至一臨時工作文件中,為確保不存在空行,
用s e d刪除空行,需要真正做的是過濾文本文件。腳本如下:
  1. #!/bin/sh
  2. # whileorder.sh
  3. INPUT_FILE=order
  4. HOLD=order.tmp
  5. if [ -s $INPUT_FILE ]; then
  6.         # zero the output file, we do not want to append!
  7.         >$HOLD
  8.         while read LINE
  9.         do      
  10.                 case $LINE in
  11.                         \#*|ITEM*);; # ignore any # or the line with ITEM
  12.                         *)
  13.                         # redirect the output to a temp file
  14.                         echo $LINE >>$HOLD
  15.                         ;;
  16.                 esac   
  17.         done <$INPUT_FILE
  18.         # use to sed to delete any empty lines, if any
  19.         sed -e '/^$/d' order.tmp >order.$
  20.         mv order.$ order.tmp
  21. else   
  22.         echo "`basename $0` : Sorry $INPUT_FILE does not exist or empty"
  23. fi      
復(fù)制代碼
執(zhí)行腳本后,輸出結(jié)果為。
[root@localhost ~]# cat order.tmp
Pens 14 12
Pencils 15 15
Pads 7 3
Disks 3 2
Sharpeners 5 1
現(xiàn)在要在另一個w h i l e循環(huán)中讀取臨時工作文件,使用e x p r對數(shù)字進(jìn)行數(shù)值運算。
  1. #!/bin/sh
  2. # whileorder2
  3. # init the variables
  4. HOLD=order.tmp
  5. RE_ORDER=0
  6. ORDERS=0
  7. STATIONERY_TOT=0
  8. if [ -s $HOLD ]; then
  9.         echo "========= STOCK RE_ORDER REPORT ========="
  10.         while read ITEM RECORD LEVEL
  11.         do
  12.                 # are we below the reorder level for this item ??
  13.                 if [ "$LEVEL" -lt "$RECORD" ];then
  14.                         # yes, do the new order amount
  15.                         NEW_ORDER=`expr $RECORD + $RECORD`
  16.                         # running total of orders
  17.                         ORDERS=`expr $ORDERS + 1`
  18.                         # running total of stock levels
  19.                         STATIONERY_TOT=`expr $STATIONERY_TOT + $LEVEL`
  20.                         echo "$ITEM need reordering to the amount $NEW_ORDER"
  21.                 fi
  22.         done <$HOLD
  23.         echo "$ORDERS new items need to be ordered"
  24.         echo "Our reorder total is $STATIONERY_TOT"
  25. else
  26.         echo "`basename $0` : Sorry $HOLD does not exists or is empty"
  27. fi
復(fù)制代碼
以下為依據(jù)報表文件運行所得輸出結(jié)果。
  1. ========= STOCK RE_ORDER REPORT =========
  2. Pens need reordering to the amount 28
  3. Pads need reordering to the amount 14
  4. Disks need reordering to the amount 6
  5. Sharpeners need reordering to the amount 10
  6. 4 new items need to be ordered
  7. Our reorder total is 18
復(fù)制代碼
將兩段腳本結(jié)合在一起很容易。實際上這本來是一個腳本,為講解方便,才將其分成兩
個。

while循環(huán)和文件描述符
第5章查看文件描述符時,提到有必要用w h i l e循環(huán)將數(shù)據(jù)讀入一個文件。使用文件描述符
3和4,下面的腳本進(jìn)行文件m y f i l e . t x t到m y f i l e . b a k的備份。注意,腳本開始測試文件是否存在,
如果不存在或沒有數(shù)據(jù),腳本立即終止。還有w h i l e循環(huán)用到了空命令(:),這是一個死循環(huán),
因為n u l l永遠(yuǎn)返回真。嘗試讀至文件結(jié)尾將返回錯誤,那時腳本也終止執(zhí)行。
  1. #!/bin/sh
  2. # copyfile.sh
  3. FILENAME=myfile.txt
  4. FILENAME_BAK=myfile.bak
  5. if [ -s $FILENAME ]; then
  6.         # open FILENAME for writing
  7.         # open FILENAME for reading
  8.         exec 4>$FILENAME_BAK
  9.         exec 3<$FILENAME
  10.         # loop forever until no more data and thus an error so we
  11.         # are at end of file
  12.         while:
  13.         do      
  14.                 read LINE <&3
  15.                 if [ "$?" -ne 0 ]; then
  16.                         # errors then close up
  17.                         exec 3<&-
  18.                         exec 4<&-
  19.                 fi      
  20.                 # write to FILENAME_BAK
  21.                 echo $LINE>&4
  22.         done   
  23. else   
  24.         echo "`basename $0` : Sorry, $FILENAME is not present or is empty" >&2
  25. fi      
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP