歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> SHELL編程

linux shell編程指南第十八章------控制流結構

在書寫正確腳本前,大概講一下退出狀態。任何命令進行時都將返回一個退出狀態。如
果要觀察其退出狀態,使用最後狀態命令:
$ echo $?
主要有4種退出狀態。前面已經講到了兩種,即最後命令退出狀態$ ?和控制次序命令( $ $、
| |)。其余兩種是處理s h e l l腳本或s h e l l退出及相應退出狀態或函數返回碼。在第1 9章講到函數
時,也將提到其返回碼。
要退出當前進程,s h e l l提供命令e x i t,一般格式為:
exit n
其中,n為一數字。
如果只在命令提示符下鍵入e x i t,假定沒有在當前狀態創建另一個s h e l l,將退出當前s h e l l。
如果在腳本中鍵入e x i t,s h e l l將試圖(通常是這樣)返回上一個命令返回值。有許多退出腳本
值,但其中相對於腳本和一般系統命令最重要的有兩種,即:
退出狀態0 退出成功,無錯誤。
退出狀態1 退出失敗,某處有錯誤。
可以在s h e l l腳本中加入自己的退出狀態(它將退出腳本)。本書鼓勵這樣做,因為另一個
s h e l l腳本或返回函數可能要從s h e l l腳本中抽取退出腳本。另外,相信加入腳本本身的退出腳
本值是一種好的編程習慣。
如果願意,用戶可以在一個用戶輸入錯誤後或一個不可覆蓋錯誤後或正常地處理結束後

退出腳本。

s h e l l會提供一系列命令聲明語句等補救措施來幫助你在命令成功或失敗時,或需要處
理一個命令清單時采取正確的動作。
這些命令語句大概分兩類:
循環和流控制。

i f、t h e n、e l s e語句提供條件測試。測試可以基於各種條件。例如文件的權限、長度、數
值或字符串的比較。這些測試返回值或者為真( 0),或者為假( 1)。基於此結果,可以進行
相關操作。在講到條件測試時已經涉及了一些測試語法。
c a s e語句允許匹配模式、單詞或值。一旦模式或值匹配,就可以基於這個匹配條件作其他
聲明。

循環或跳轉是一系列命令的重復執行過程,本書提到了3種循環語句:
for 循環每次處理依次列表內信息,直至循環耗盡。
Until 循環此循環語句不常使用, u n t i l循環直至條件為真。條件部分在循環末尾部分。
While 循環w h i l e循環當條件為真時,循環執行,條件部分在循環頭。
流控制語句的任何循環均可嵌套使用,例如可以在一個f o r循環中嵌入另一個f o r循環。
現在開始講解循環和控制流,並舉一些腳本實例。


i f語句測試條件,測試條件返回真( 0)或假(1)後,可相應執行一系列語句。i f語句結
構對錯誤檢查非常有用。其格式為:
if 條件1
then 命令1
elif 條件2
then 命令2
else 命令3

f i
讓我們來具體講解i f語句的各部分功能。
If 條件1 如果條件1為真
Then 那麼
命令1 執行命令1
elif 條件2 如果條件1不成立
then 那麼
命令2 執行命令2
else 如果條件1,2均不成立
命令3 那麼執行命令3
fi 完成
i f語句必須以單詞f i終止。在i f語句中漏寫f i是最一般的錯誤。我自己有時也是這樣。
e l i f和e l s e為可選項,如果語句中沒有否則部分,那麼就不需要e l i f和e l s e部分。I f語句可以
有許多e l i f部分。最常用的i f語句是if then fi結構。

最普通的i f語句是:
i f條件
then 命令
f i
使用i f語句時,必須將t h e n部分放在新行,否則會產生錯誤。如果要不分行,必須使用命
令分隔符。本書其余部分將采取這種形式。現在簡單i f語句變為:
if 條件;t h e n
命令
f i

[root@localhost huangcd]# sh iftest2
enter your name:
your did not enter a information
[root@localhost huangcd]# cat iftest2
#!/bin/bash
echo -n "enter your name:"
read NAME
if [ "$NAME" = "" ];then
echo "your did not enter a information"
fi

下面測試文件拷貝是否正常,如果c p命令並沒有拷貝文件m y f i l e到m y f i l e . b a k,則打印錯
誤信息。注意錯誤信息中` basename $0`打印腳本名。
如果腳本錯誤退出,一個好習慣是顯示腳本名並將之定向到標准錯誤中。用戶應該知道
產生錯誤的腳本名。

[root@localhost huangcd]# cat ifcp
#!/bin/bash
if cp ok1.txt ok.bak;then
echo "good copy"
else
echo "`basename $0`:error could not copy the files">&2
fi
[root@localhost huangcd]# ./ifcp
cp: 無法 stat “ok1.txt”: 沒有那個文件或目錄
ifcp:error could not copy the files

2代表標准出錯,如果文件不存在,如果不加上2>&1則會打印出錯信息,
加上以後就不會打印了,也進入那個文件了
&1代表標准輸出定向到的地方,這句相當於
cat cities > cities.copy 2> cities.copy
或者
cat cities 1> cities.copy 2> cities.copy
或者
cat cities 2> cities.copy 1> &2

0:標准輸入,1:標准輸出,2:標准出錯

當運行一些管理腳本時,可能要在根目錄下運行它,特別是移動某種全局文件或進行權
限改變時。一個簡單的測試可以獲知是否運行在根目錄下。下面腳本中變量D I R E C TO RY使用
當前目錄的命令替換操作,然後此變量值與" / "字符串比較( /為根目錄)。如果變量值與字符
串不等,則用戶退出腳本,退出狀態為1意味錯誤信息產生。

[root@localhost huangcd]# ./ifpwd
you need to be in the root directory.not /home/huangcd
[root@localhost huangcd]# cat ifpwd
#!/bin/bash
DIRCTORY=`pwd`
if [ "$DIRCTORY"!="/" ]
then echo "you need to be in the root directory.not $DIRCTORY ">&2
exit 1
fi

i f語句可用來測試傳入腳本中參數的個數。使用特定變量$ #,表示調用參數的個數。可以
測試所需參數個數與調用參數個數是否相等。
以下測試確保腳本有三個參數。如果沒有,則返回一個可用信息到標准錯誤,然後代碼
退出並顯示退出狀態。如果參數數目等於3,則顯示所有參數。

[root@localhost huangcd]# cat ifpatam
#!/bin/bash
if [ $# -lt 3 ]
then echo "Usage:`basename $0` arg1 arg2 arg3" >&2
exit 1
fi
echo "arg1:$1"
echo "arg2:$2"
echo "arg3:$3"
[root@localhost huangcd]# ./ifpatam cup medal
Usage:ifpatam arg1 arg2 arg3
[root@localhost huangcd]# ./ifpatam cup medal thophy
arg1:cup
arg2:medal
arg3:thophy

下面的例子測試環境變量E D I TO R是否已設置。如果E D I TO R變量為空,將此信息通知用
戶。如果已設置,在屏幕上顯示編輯類型。

[root@localhost huangcd]# cat ifeditor
#!/bin/bash
if [-z $EDITORS ]
then echo "your EDITOR environment is not set"
else
echo "Using $EDITOR as the fefault editor"
fi
[root@localhost huangcd]# ./ifeditor
./ifeditor: line 2: [-z: command not found
Using as the fefault editor

可以向腳本傳遞位置參數,然後測試變量。這裡,如果用戶在腳本名字後鍵入目錄名,
腳本將重設$ 1特殊變量為一更有意義的名字。即D I R E C TO RY。這裡需測試目錄是否為空,如
果目錄為空,ls -A將返回空,然後對此返回一信息。

[root@localhost huangcd]# sh ifdirec
is indeed empty
[root@localhost huangcd]# sh ifdirec /home
/home is indeed empty
[root@localhost huangcd]# cat ifdirec
#!/bin/bash
DIRECTORY=$1
if [ "`ls -A $DIRECTORY`"="" ]
then echo "$DIRECTORY is indeed empty"
else
echo "$DIRECTORY is not empty"
fi

Copyright © Linux教程網 All Rights Reserved