Until語句 While語句中,只要某條件為真,則重復執行循環代碼,until語句正好同while相反,該語句使循環代碼重復執行,直到遇到某一條件為真才停止。
Until語句的結構如下:
until command
do
command
command
… …
done
可以用until語句替換上面備份程序的while語句,完成同樣的功能:
until [ $ANS != Y -a $ANS != y ]
for 循環
在介紹for循環之前,我們要學個非常有用的unix命令:shift。我們知道,對於位置變量或命令行參數,其個數必須是確定的,或者當Shell程序不知道其個數時,可以把所有參數一起賦值給變量$*。若用戶要求Shell在不知道位置變量個數的情況下,還能逐個的把參數一一處理,也就是在$1後為$2,在$2後面為$3等。在 shift命令執行前變量$1的值在shift命令執行後就不可用了。
示例如下:
#測試shift命令(x_shift.sh)
until [ $# -eq 0 ]
do
echo "第一個參數為: $1 參數個數為: $#"
shift
done
執行以上程序x_shift.sh:
$./x_shift.sh 1 2 3 4
結果顯示如下:
第一個參數為: 1 參數個數為: 3
第一個參數為: 2 參數個數為: 2
第一個參數為: 3 參數個數為: 1
第一個參數為: 4 參數個數為: 0
從上可知shift命令每執行一次,變量的個數($#)減一,而變量值提前一位,下面代碼用until和shift命令計算所有命令行參數的和。
#shift上檔命令的應用(x_shift2.sh)
if [ $# -eq 0 ]
then
echo "Usage:x_shift2.sh 參數"
exit 1
fi
sum=0
until [ $# -eq 0 ]
do
sum=`expr $sum + $1`
shift
done
echo "sum is: $sum"
執行上述程序:
$x_shift2.sh 10 20 15
其顯示結果為:
45
shift命令還有另外一個重要用途,Bsh定義了9個位置變量,從$1到$9,這並不意味著用戶在命令行只能使用9個參數,借助shift命令可以訪問多於9個的參數。
Shift命令一次移動參數的個數由其所帶的參數指定。例如當shell程序處理完前九個命令行參數後,可以使用shift 9命令把$10移到$1。
在熟悉了shift命令後,我們一起看看,Bsh程序中非常有用的for循環語句,這種循環同上面說的while和until循環不同,for語句中的循環是否執行並不由某個條件的真和假來決定,決定for循環是否繼續的條件是參數表中是否還有未處理的參數。
For語句的結構如下:
for variable in arg1 arg2 … argn
do
command
command
… …
done
下面是for循環的簡單例子:
for LETTER in a b c d
do
echo $LETTER
done
程序執行結果如下:
a
b
c
d
在上面計算參數和的例子中,我們可以用for循環,實現如下:
#測試 for 程序(x_for.sh)
if [ $# -eq 0 ]
then
echo "Usage:x_for.sh 參數… …"
exit 1
fi
sum=0
for I in $*
do
sum=`expr $sum + $I`
done
echo "sum is: $sum"
中斷循環指令 在程序循環語句中,我們有時候希望遇到某中情況時候結束本次循環執行下次循環或結束這個循環,這就涉及到兩條語句:continue和break。continue命令可使程序忽略其後循環體中的其他指令,直接進行下次循環,而break命令則立刻結束循環,執行循環體後面的的語句。
#測試continue
I=1
while [ $I -lt 10 ]
do
if [ $I -eq 3 ]
then
continue
fi
if [ $I -eq 7 ]
then
break
fi
echo "$I\c"
done
執行上面程序,結果如下:
12456789
與或結構
使用與/或結構有條件的執行命令
Shell程序中可以使用多種不同的方法完成相同的功能,例如until和while語句就可以完成相同的功能,同樣,除了if-then-else結構可以使命令有條件的執行外,$$和||操作符也能完成上述功能。在C語言中這兩個操作符分別表示邏輯與和邏輯或操作。在Bourne Shell中,用&&連接兩條命令的含義只有前面一條命令成功執行了,後面的命令才會執行。
&&操作的形式為:
command && command
例如語句:
rm $TEMPDIR/* && echo "Files successfully removed"
只有rm命令成功執行以後,才會執行echo命令。若用if-then語句實現上述功能,形式為:
if rm $TEMPDIR/*
then
echo "Files successfully removed"
fi
相反,用||連接兩條命令的含義為只有第一條命令執行失敗才執行第二條命令,例如:
rm $TEMPDIR/* || echo "File were not removed"
上面語句的等價形式為:
if rm $TEMPDIR/*
then
:
else
echo "Files were not removed"
fi
這兩種操作符可以聯合使用,如在下面的命令行中,只有command1和command2執行成功後,command3才會執行:
command1 && command2 && command3
下面的命令行表示只有command1成功執行,command2不成功執行時,才會執行command3。
&&和||操作符可以簡化命令條件執行的格式,但一般只用於一條命令的條件執行。如果許多命令都使用這兩個操作符,那麼整個程序的可讀性將變的很差,所以在多條命令的條件執行時,最好采用可讀性好的if語句。
函數 現在我們介紹Shell程序中的函數部分,基本上任何高級語言都支持函數這個東西,能讓我們勝好多事情的東西,至少省的頻繁的敲擊相同的東西,好了come onShell程序中的函數
函數又叫做子程序,可以在程序中的任何地方被調用,其格式如下:
函數名字()
{
command
... ...
command;
}
Shell程序的任何地方都可以用命令 "函數名字" 調用,使用函數的好處有兩點,一點是使用函數可以把一個復雜的程序化為多個模塊,易於管理,符合結構化程序的設計思想,另一個好處是代碼的重用。
Shell函數和Shel程序比較相似,它們的區別在於Shell程序在子Shell中運行,而Shell函數在當前Shell中運行。因此,在當前Shell中可以看到Shell函數對變量的修改。在任何Shell中都可以定義函數,包括交互式Shell。
例如:
$dir() {ls -l;}
結果是我們在$後面打dir,其顯示結果同ls -l的作用是相同的。該dir函數將一直保留到用戶從系統退出,或執行了如下所示的unset命令:
$unset dir
下面的例子說明了函數還可以接受位置參數:
$dir(){_
>echo "permission ln owner group file sz last access
>ls -l $*;
>}
運行 dir a* 看產生什麼結果
參數a*傳遞到dir函數中並且代替了$*
通常Shell程序將在子Shell中執行,該程序對變量的改變只在子Shell中有效而在當前Shell中無效。"."命令可以使Shell程序在當前Shell中執行。用戶可以在當前Shell中定義函數和對變量賦值。通常用下面命令來重新初使化.profile對Shell環境的設置。
$ . .profile
由於看到這部分相對簡單,我們還是順便說說trap好了
使用trap命令進行例外處理 用戶編寫程序在程序運行時可能會發生一些例外情況,比如執行該程序的用戶按中斷鍵或使用kill命令,或者控制終端突然與系統斷開等。unix系統中的上述情況會使系統向進程發一個信號,通常情況下該信號使進程終止運行。有時侯用戶希望進程在接到終止信號時進行一些特殊的操作。若進程在運行時產生一些臨時文件,又因接受到的信號而終止。那麼該進程產生的臨時文件將保留下來。在bsh中,用戶可以使用trap命令修改進程接收到終止信號時進行的默認操作。
trap命令格式如下:
trap command_string signals
多數系統中共有15種發給進程的信號,默認情況下大多數信號都會使程序終止。用戶最好查閱自己系統的文擋,看看本系統內使用的信號種類。除了信號為9(真正的kill信號)不能使用trap命令外,其他信號所帶來的操作都可以用trap命令進行指定。下面是trap命令中經常使用的幾種信號:
信號 功能
1 掛起
2 操作中斷
15 軟終止(kill信號)
若命令串中包含不只