shell中if和相關判斷符

來源:互聯網
上載者:User

標籤:character   socket   file   

1. 關於某個檔名的『類型』偵測(存在與否),如 test -e filename

-e 該『檔名』是否存在?(常用)

-f 該『檔名』是否為檔案(file)?(常用)

-d 該『檔案名稱』是否為目錄(directory)?(常用)

-b 該『檔案名稱』是否為一個 block device 裝置?

-c 該『檔案名稱』是否為一個 character device 裝置?

-S 該『檔名』是否為一個 Socket 檔案?

-p 該『檔名』是否為一個 FIFO (pipe) 檔案?

-L 該『檔名』是否為一個連結檔?

 

2. 關於檔案的許可權偵測,如 test -r filename

-r 偵測該檔案名稱是否具有『可讀』的屬性?

-w 偵測該檔名是否具有『可寫』的屬性?

-x 偵測該檔名是否具有『可執行』的屬性?

-u 偵測該檔案名稱是否具有『SUID』的屬性?

-g 偵測該檔案名稱是否具有『SGID』的屬性?

-k 偵測該檔案名稱是否具有『Sticky bit』的屬性?

-s 偵測該檔名是否為『非空白檔案』?

 

3. 兩個檔案之間的比較,如: test file1 -nt file2

-nt (newer than)判斷 file1 是否比 file2 新

-ot (older than)判斷 file1 是否比 file2 舊

-ef 判斷 file2 與 file2 是否為同一檔案,可用在判斷 hard link 的判定上。 主要意義在判定,兩個檔案是否均指向同一個 inode 哩!

 

4. 關於兩個整數之間的判定,例如 test n1 -eq n2

-eq 兩數值相等 (equal)

-ne 兩數值不等 (not equal)

-gt n1 大於 n2 (greater than)

-lt n1 小於 n2 (less than)

-ge n1 大於等於 n2 (greater than or equal)

-le n1 小於等於 n2 (less than or equal)

 

5. 判定字串的資料

test -z string 判定字串是否為 0 ?若 string 為空白字串,則為 true

test -n string 判定字串是否非為 0 ?若 string 為空白字串,則為 false。

註: -n 亦可省略

test str1 = str2 判定 str1 是否等於 str2 ,若相等,則回傳 true

test str1 != str2 判定 str1 是否不等於 str2 ,若相等,則回傳 false

 

6. 多重條件判定,例如: test -r filename -a -x filename

-a (and)兩狀況同時成立!例如 test -r file -a -x file,則 file 同時具有 r 與 x 許可權時,才回傳 true。

-o (or)兩狀況任何一個成立!例如 test -r file -o -x file,則 file 具有 r 或 x 許可權時,就可回傳 true。

! 反相狀態,如 test ! -x file ,當 file 不具有 x 時,回傳 true

 

5. Shell指令碼文法上一頁第 31 章 Shell指令碼下一頁

--------------------------------------------------------------------------------

5. Shell指令碼文法 請點評5.1. 條件測試:test [ 請點評

命令test或[可以測試一個條件是否成立,如果測試結果為真,則該命令的Exit Status為0,如果測試結果為假,則命令的Exit Status為1(注意與C語言的邏輯表示正好相反)。例如測試兩個數的大小關係:

 

$ VAR=2$ test $VAR -gt 1$ echo $?0$ test $VAR -gt 3$ echo $?1$ [ $VAR -gt 3 ]$ echo $?1

雖然看起來很奇怪,但左方括弧[確實是一個命令的名字,傳給命令的各參數之間應該用空格隔開,比如,$VAR、-gt、3、]是[命令的四個參數,它們之間必須用空格隔開。命令test或[的參數形式是相同的,只不過test命令不需要]參數。以[命令為例,常見的測試命令如下表所示:

 

表 31.2. 測試命令

 

[ -d DIR ]如果DIR存在並且是一個目錄則為真[ -f FILE ]如果FILE存在且是一個普通檔案則為真[ -z STRING ]如果STRING的長度為零則為真[ -n STRING ]如果STRING的長度非零則為真[ STRING1 = STRING2 ]如果兩個字串相同則為真[ STRING1 != STRING2 ]如果字串不相同則為真[ ARG1 OP ARG2 ]ARG1和ARG2應該是整數或者取值為整數的變數,OP是-eq(等於)-ne(不等於)-lt(小於)-le(小於等於)-gt(大於)-ge(大於等於)之中的一個

 

和C語言類似,測試條件之間還可以做與、或、非邏輯運算:

 

表 31.3. 帶與、或、非的測試命令

 

[ ! EXPR ]EXPR可以是上表中的任意一種測試條件,!表示邏輯反[ EXPR1 -a EXPR2 ]EXPR1和EXPR2可以是上表中的任意一種測試條件,-a表示邏輯與[ EXPR1 -o EXPR2 ]EXPR1和EXPR2可以是上表中的任意一種測試條件,-o表示邏輯或

 

例如:

 

$ VAR=abc$ [ -d Desktop -a $VAR = ‘abc‘ ]$ echo $?0

注意,如果上例中的$VAR變數事先沒有定義,則被Shell展開為空白字串,會造成測試條件的語法錯誤(展開為[ -d Desktop -a = ‘abc‘ ]),作為一種好的Shell編程習慣,應該總是把變數取值放在雙引號之中(展開為[ -d Desktop -a "" = ‘abc‘ ]):

 

$ unset VAR$ [ -d Desktop -a $VAR = ‘abc‘ ]bash: [: too many arguments$ [ -d Desktop -a "$VAR" = ‘abc‘ ]$ echo $?15.2. if/then/elif/else/fi 請點評

和C語言類似,在Shell中用if、then、elif、else、fi這幾條命令實現分支控制。這種流程式控制制語句本質上也是由若干條Shell命令組成的,例如先前講過的

 

if [ -f ~/.bashrc ]; then . ~/.bashrcfi

其實是三條命令,if [ -f ~/.bashrc ]是第一條,then . ~/.bashrc是第二條,fi是第三條。如果兩條命令寫在同一行則需要用;號隔開,一行唯寫一條命令就不需要寫;號了,另外,then後面有換行,但這條命令沒寫完,Shell會自動續行,把下一行接在then後面當作一條命令處理。和[命令一樣,要注意命令和各參數之間必須用空格隔開。if命令的參數組成一條子命令,如果該子命令的Exit Status為0(表示真),則執行then後面的子命令,如果Exit Status非0(表示假),則執行elif、else或者fi後面的子命令。if後面的子命令通常是測試命令,但也可以是其它命令。Shell指令碼沒有{}括弧,所以用fi表示if語句塊的結束。見下例:

 

#! /bin/shif [ -f /bin/bash ]then echo "/bin/bash is a file"else echo "/bin/bash is NOT a file"fiif :; then echo "always true"; fi

:是一個特殊的命令,稱為空白命令,該命令不做任何事,但Exit Status總是真。此外,也可以執行/bin/true或/bin/false得到真或假的Exit Status。再看一個例子:

 

#! /bin/shecho "Is it morning? Please answer yes or no."read YES_OR_NOif [ "$YES_OR_NO" = "yes" ]; then echo "Good morning!"elif [ "$YES_OR_NO" = "no" ]; then echo "Good afternoon!"else echo "Sorry, $YES_OR_NO not recognized. Enter yes or no." exit 1fiexit 0

上例中的read命令的作用是等待使用者輸入一行字串,將該字串存到一個Shell變數中。

 

此外,Shell還提供了&&和||文法,和C語言類似,具有Short- circuit特性,很多Shell指令碼喜歡寫成這樣:

 

test "$(whoami)" != ‘root‘ && (echo you are using a non-privileged account; exit 1)

&& 相當於“if...then...”,而||相當於“if not...then...”。&&和||用於串連兩個命令,而上面講的-a和-o僅用於在測試運算式中串連兩個測試條件,要注意它們的區別,例如,

 

test "$VAR" -gt 1 -a "$VAR" -lt 3

和以下寫法是等價的

 

test "$VAR" -gt 1 && test "$VAR" -lt 35.3. case/esac 請點評

case命令可類比C語言的switch/case語句,esac表示case語句塊的結束。C語言的case只能匹配整型或字元型常量運算式,而Shell指令碼的case可以匹配字串和Wildcard,每個匹配分支可以有若干條命令,末尾必須以;;結束,執行時找到第一個匹配的分支並執行相應的命令,然後直接跳到esac之後,不需要像C語言一樣用break跳出。

 

#! /bin/shecho "Is it morning? Please answer yes or no."read YES_OR_NOcase "$YES_OR_NO" inyes|y|Yes|YES) echo "Good Morning!";;[nN]*) echo "Good Afternoon!";;*) echo "Sorry, $YES_OR_NO not recognized. Enter yes or no." exit 1;;esacexit 0

使用case語句的例子可以在系統服務的指令碼目錄/etc/init.d中找到。這個目錄下的指令碼大多具有這種形式(以/etc/apache2為例):

 

case $1 in start) ... ;; stop) ... ;; reload | force-reload) ... ;; restart) ... *) log_success_msg "Usage: /etc/init.d/apache2 {start|stop|restart|reload|force-reload|start-htcacheclean|stop-htcacheclean}" exit 1 ;;esac

啟動apache2服務的命令是

 

$ sudo /etc/init.d/apache2 start

$1是一個特殊變數,在執行指令碼時自動取值為第一個命令列參數,也就是start,所以進入start)分支執行相關的命令。同理,命令列參數指定為stop、reload或restart可以進入其它分支執行停止服務、重新載入設定檔或重新啟動服務的相關命令。

 

5.4. for/do/done 請點評

Shell指令碼的for迴圈結構和C語言很不一樣,它類似於某些程式設計語言的foreach迴圈。例如:

 

#! /bin/shfor FRUIT in apple banana pear; do echo "I like $FRUIT"done

FRUIT是一個迴圈變數,第一次迴圈$FRUIT的取值是apple,第二次取值是banana,第三次取值是pear。再比如,要將目前的目錄下的chap0、chap1、chap2等檔案名稱改為chap0~、chap1~、chap2~等(按慣例,末尾有~字元的檔案名稱表示臨時檔案),這個命令可以這樣寫:

 

$ for FILENAME in chap?; do mv $FILENAME $FILENAME~; done

也可以這樣寫:

 

$ for FILENAME in `ls chap?`; do mv $FILENAME $FILENAME~; done5.5. while/do/done 請點評

while的用法和C語言類似。比如一個驗證密碼的指令碼:

 

#! /bin/shecho "Enter password:"read TRYwhile [ "$TRY" != "secret" ]; do echo "Sorry, try again" read TRYdone

下面的例子通過算術運算控制迴圈的次數:

 

#! /bin/shCOUNTER=1while [ "$COUNTER" -lt 10 ]; do echo "Here we go again" COUNTER=$(($COUNTER+1))done

Shell還有until迴圈,類似C語言的do...while迴圈。本章從略。

 

習題 請點評

1、把上面驗證密碼的程式修改一下,如果使用者輸錯五次密碼就報錯退出。

 

5.6. 位置參數和特殊變數 請點評

有很多特殊變數是被Shell自動賦值的,我們已經遇到了$?和$1,現在總結一下:

 

表 31.4. 常用的位置參數和特殊變數

 

$0相當於C語言main函數的argv[0]$1、$2...這些稱為位置參數(Positional Parameter),相當於C 語言main函數的argv[1]、argv[2]...$#相當於C語言main函數的argc - 1,注意這裡的#後面不表示注釋[email protected]表示參數列表"$1" "$2" ...,例如可以用在for迴圈中的in後面。$?上一條命令的Exit Status$$當前Shell的進程號

 

位置參數可以用shift命令左移。比如shift 3表示原來的$4現在變成$1,原來的$5現在變成$2等等,原來的$1、$2、$3丟棄,$0不移動。不帶參數的shift命令相當於shift 1。例如:

 

#! /bin/shecho "The program $0 is now running"echo "The first parameter is $1"echo "The second parameter is $2"echo "The parameter list is [email protected]"shiftecho "The first parameter is $1"echo "The second parameter is $2"echo "The parameter list is [email protected]"5.7. 函數 請點評

和C語言類似,Shell中也有函數的概念,但是函數定義中沒有傳回值也沒有參數列表。例如:

 

#! /bin/shfoo(){ echo "Function foo is called";}echo "-=start=-"fooecho "-=end=-"

注意函數體的左花括弧{和後面的命令之間必須有空格或換行,如果將最後一條命令和右花括弧}寫在同一行,命令末尾必須有;號。

 

在定義foo()函數時並不執行函數體中的命令,就像定義變數一樣,只是給foo這個名字一個定義,到後面調用foo函數的時候(注意Shell中的函數調用不寫括弧)才執行函數體中的命令。Shell指令碼中的函數必須先定義後調用,一般把函數定義都寫在指令碼的前面,把函數調用和其它命令寫在指令碼的最後(類似C語言中的main函數,這才是整個指令碼實際開始執行命令的地方)。

 

Shell函數沒有參數列表並不表示不能傳參數,事實上,函數就像是迷你指令碼,調用函數時可以傳任意個參數,在函數內同樣是用$0、$1、$2等變數來提取參數,函數中的位置參數相當於函數的局部變數,改變這些變數並不會影響函數外面的$0、$1、$2等變數。函數中可以用return命令返回,如果return後面跟一個數字則表示函數的Exit Status。

 

下面這個指令碼可以一次建立多個目錄,各目錄名通過命令列參數傳入,指令碼逐個測試各目錄是否存在,如果目錄不存在,首先列印資訊然後試著建立該目錄。

 

#! /bin/shis_directory(){ DIR_NAME=$1 if [ ! -d $DIR_NAME ]; then return 1 else return 0 fi}for DIR in "[email protected]"; do if is_directory "$DIR" then : else echo "$DIR doesn‘t exist. Creating it now..." mkdir $DIR > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "Cannot create directory $DIR" exit 1 fi fidone

注意is_directory()返回0表示真返回1表示假。


本文出自 “懶懶” 部落格,請務必保留此出處http://5675012.blog.51cto.com/5665012/1600967

shell中if和相關判斷符

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.