1. 程式人生 > >shell編程(三)

shell編程(三)

acl efm dsa mfc ofa ans ebp else cep

通過前兩篇文章,我們掌握了shell的一些基本寫法和變量的使用,以及基本數據類型的運算。那麽,本次就將要學習shell的結構化命令了,也就是我們其它編程語言中的條件選擇語句及循環語句。

不過,在學習shell結構化命令的時候,我們又會發現它與其它編程的語言相比存在不小的區別。下面就開始看看吧:

條件選擇

在條件選擇語句中,主要包含以下幾種寫法:

if-then語句

if command
then
    commands
fi

 
例如:
技術分享


技術分享


吃瓜群眾表示一臉懵比:if語句後面接的是命令,我們其它編程語言中,這兒都是接返回布爾值(true,false)的表達式。

那麽這到底是怎麽回事呢?

在shell腳本的if其實是根據緊跟後面的那個命令的退出狀態碼來判斷是否執行then後面的語句的。

關於退出狀態碼,你只需要記住:正常退出(命令執行正常)的狀態碼是0, 非正常退出的狀態碼不是0(有不少)。

以上語句的語義為: 如果if後面的命令執行正常(狀態碼0),那麽就執行then後面的語句。否則不執行。 fi代表if語句的結束。

#!/bin/bash
#這兒由於pwd是linux內置的命令,因此執行後會正常退出(狀態碼0),所以會執行then中的語句
#如果此處替換為一個不存在的命令(例如: pw),那麽就會非正常退出,不會執行then中的語句
if pwd
then
   echo 執行then裏面的語句
fi

 

if-then還可以簡寫為

if command; then
    commands
fi

 

因此,以上代碼還可以寫成以下:

#!/bin/bash
if pwd; then
   echo 執行then裏面的語句
fi

 

以上,如果我要判斷處理異常退出(狀態碼非0)情況,該怎麽辦?

別著急: else 來幫你。

if-then-else語句

if command
then
    commands
else
    commands
fi

 

與if-then語句相比,這回多了個else語句,else語句用來判斷if後面的命令非正常退出的情況。

#!/bin/bash
if pwd
then
    echo 正常退出
else 
    echo 非正常退出
fi   

甚至,我們還可以變形寫出更多的else:

if command1 
then
    commands 
elif 
    command2 
then
    command3
fi

 

但是上面就只能根據退出狀態碼判斷,不能寫表達式,你還讓我怎麽寫? 我各個編程語言直接吊打你!

不要慌,客官,請接著往下看:

test命令

test命令用於if-then或者if-then-else語句中,主要用於判斷列出的條件是否成立,如果成立,就會退出並返回退出狀態碼0,否則返回非0。

這意味著我們可以通過test命令來寫表達式命令了。不過,對於已習慣其它編程語言的程序猿們(沒學過的除外),不要高興得太早,前方有坑,至於是什麽坑,待會兒就能看到。

先看看test命令的基本用法吧:

直接用:

test condition

 

結合if-then語句用

if  test condition
then
    commands
fi

結合if-then-else語句用

if  test condition
then
    commands
else 
    commands    
fi

條件成立就執行then語句,否則else語句。

test命令只能判斷一下三類條件:

  • 數值比較
  • 字符串比較
  • 文件比較

例如:if test用法:

[rwwwwst@iz2ze46xiz ~]# cat wwww.sh
if test $[5<3]
        then echo 5小於3
else echo 5大於3
fi

運行結果:

[rwwwwwwwwwt@iz2ze46x ~]# ./wwww.sh
5小於3

數值比較

比較描述
n1 -eq n2 判斷n1是否等於n2
n1 -ge n2 判斷n1是否大於或等於n2
n1 -gt n2 判斷n1是否大於n2
n1 -le n2 判斷n1是否小於或等於n2
n1 -lt n2 判斷n1是否小於n2
n1 -ne n2 判斷n1是否不等於n2

特別提醒: 以上表格不用你去記住,在命令行下面, 執行man test就能看到這些了。後面的對與另外兩種比較的同理

#!/bin/bash
num1=100
num2=200
if test $num1 -eq $num2
then
    echo num1等於num2
else
    echo num2不等於num2
fi

 

好好的標準的數學比較符號不能使用,難道非得寫這種文本形式?是不是覺得很別扭?
不著急,還有替代方案:

使用雙括號

雙括號命令允許你在比較過程中使用高級數學表達式。關鍵是使用雙括號,咱就可以用數學比較符號啦(等於==, 大於>, 小於< 等等都能使用啦)。
使用方法:

(( expression ))

註意:括號裏面兩邊都需要有空格

#!/bin/bash
num1=100
num2=200
if (( num1 > num2 )) 
then
    echo "num1 > num2"
else 
    echo "num2 <= num2"  

 

字符串比較

比較描述
str1 = str2 判斷str1是否與str2相同
str1 != str2 判斷str1是否與str2不相同
str1 < str2 判斷str1是否比str2小(根據ASCII)
str1 > str2 判斷str1是否比str2大(根據ASCII)
-n str1 判斷str1的長度是否非0
-z str1 判斷str1的長度是否為0

程序猿們,要罵的就盡情釋放吧。我反正是罵了。

test命令和測試表達式使用標準的數學比較符號來表示字符串比較,而用文本代碼來表 示數值比較。這與其它語言相比都不一樣。

#!/bin/bash
var1=test
var2=Test
if test $var1 = $str2
then
    echo 相等
else 
    echo 不相等
fi

 

註意,在使用大於(>)或小於(<)符號時,需要轉義(\>)(\<),不然會把這兩種符號時別為重定向(後面文章才會講到)。

吐槽模式開啟:我要用個比較符號,還要轉義,很蛋疼的設計!

不要慌,大招一般都在後面:

使用雙方括號

雙方括號命令提供了針對字符串比較的高級特性。它不僅解決了使用test所帶來的一系列毛病,還提供了一些test命令所沒有的高級用法。雙方括號命令的格式如下:

[[ expression ]]    

註意,可能有些shell不支持此種寫法。不過bash完美支持。以上寫法註意括號內兩邊都有空格。

#!/bin/bash
var1=test
var2=Test
if [[ $test < $test2 ]]
then
    echo "test1 < test2"
else
    echo "test1 >= test2"
fi   

這下終於不用轉義了。

文件比較

對於文件的比較,其實跟上面差不多,都是用test命令。由於篇幅有限,我這兒就不多寫了。通過man test命令可以看到具體的用法。

case語句

在使用if-then-else語句中,如果碰到條件很多的情況,如下:

#!/bin/bash
num=3
if (( $num == 1 ))
then
    echo "num=1"
elif (( $num == 2 ))
then
    echo "num=2"
elif (( $num == 3 ))
then
    echo "num=3"    
elif (( $num == 4 ))
then
    echo "num=4"
fi 

如果再多點條件,看起來是不是很多?
此時,其實還有一種替代方案,那就是使用case.

case variable in
pattern1 | pattern2) commands1;; pattern3) commands2;;
*) default commands;;
esac

 

將以上代碼替換為case:

#!/bin/bash
num=3
case $num in 1) echo "num=1";; 2) echo "num=2";; 3) echo "num=3";; 4) echo "num=4";; *) echo "defaul";; esac

技術分享

小結

  本篇主要講了條件語句。shell中的條件語句與其他編程語言相比有不小的區別,最大的區別就在於條件語句後接的是命令,而不是布爾值, 是根據命令執行退出的狀態碼來決定是否進入then語句的。這點需要牢記。

shell編程(三)