Linux shell程序設計(六).控制結構-1
?
??? 開始進入變成的實質性部分——語句結構。其中的if語句的復雜度超過了我的想象,特別是那幾個不同的種類,需要好好研究研究。
?
?
一、if語句
?
1、
測試語句條件
?
??? if 測試語句
??? then 命令1
??? else 命令2
??? fi
?
??? 舉例:
??? if test -f "$1"
??? then pr $1
??? elif test -d "$1"
??? then (cd $1 ; pr *)
??? else echo "$1 is neither a file nor a directory."
??? fi
??? 說明:如果$1是一個普通文件名,則打印其內容,如果$1是一個文件夾地址,則打印其下所有文件的內容,如果均不是,則顯示錯誤信息。
?
2、命令語句條件
?
??? 通常if語句都用test命令測試,但是也可以利用一般命令執行成功與否來做判斷。
??? 如果執行成功,則返回0,if條件為真;否則為假。
?
??? if 命令表1
??? then 命令表2
??? else 命令表3
??? fi
?
??? 舉例:
??? if
????? grep $user /etc/passwd > /tmp/null
????? who | grep $user
??? then
????? echo "$user has logged in the system."
????? cp /tmp/null tmp1
????? rm /tmp/null
??? else
????? echo "$user has not logged in the system."
??? fi
??? 說明:如果輸入用戶已經注冊,則將信息寫入tmp1中,若未注冊則返回錯誤信息。
?
?
二、條件測試
?
??? 條件測試有3中形式:
?
??? ① 用test命令 --test -f "$1"
??? ② 用[]括起來([]里面必須要有空格) --[ -f "$1"]
??? ③ 用[[條件表達式]]的格式
?
??? test命令可以和多種系統運算符一起使用,主要包括以下幾類:
?
1、文件類測試
?
??? ① -r 文件名:文件存在且可讀,則返回true
??? ② -w 文件名:文件存在且可寫,則返回true
??? ③ -x 文件名:文件存在且可執行,則返回true
??? ④ -f 文件名:文件存在且為普通文件,則返回true
??? ⑤ -d 文件名:文件存在且為目錄文件,則返回true
??? ⑥ -p 文件名:文件存在且為命名的FIFO文件,則返回true
??? ⑦ -b 文件名:文件存在且是塊設備文件,則返回true
??? ⑧ -c 文件名:文件存在且是字符設備文件,則返回true
??? ⑨ -s 文件名:文件存在且長度大于0,則返回true
??? ⑩ -t 描述字:若文件被打開且描述字與終端設備相關,則返回true(默認描述字為1)
?
2、字符串測試
?
??? ① -z s1:若字符串s1長度為0,則返回true
??? ② -n s1:若字符串s1長度大于0,則返回true
??? ③ s1:若字符串s1存在且部位空,則返回true
??? ④ s1 = s2:若s1、s2相等,則返回true(“=”可以用“==”代替,“=”前后必須有空格)
??? ⑤ s1 != s2:若s1、s2不相等,則返回true
??? ⑥ s1 < s2:若按字典順序s1在s2之前,則返回true
??? ⑦ s1 > s2:若按字典順序s1在s2之畫后,則返回true
3、數值測試
?
??? ① n1 -eq n2:若n1等于n2,則返回true
??? ② n1 -ne n2:若n1不等于n2,則返回true
??? ③ n1 -lt n2:若n1小于n2,則返回true
??? ④ n1 -le n2:若n1小于等于n2,則返回true
??? ⑤ n1 -gt n2:若n1大于n2,則返回true
??? ⑥ n1 -ge n2:若n1大于等于n2,則返回true
4、邏輯運算符
?
??? 邏輯運算符是用于將以上測試語句組合起來的符號
?
??? ① !:邏輯非,放在表達式的最前面,使表達式最終結果相反。
??? ② -a:邏輯與,放在兩個表達式之間 &&
??? ③ -o:邏輯或,放在兩個表達式之間 ||
??? ④ ():用于劃分邏輯運算
??? 舉例:
??? [ ! -r $1 ]
??? !test -r "$1"
??? [ -f "$myfile" -a -r "$myfile" ]
??? [ "$a" -ge 0 -o "$b" -le 100 ]
??? [ \( "$a" -ge 0 -o "$b" -le 100 \) -a "$c" -eq 10 ]
?
??? 優先級:
??? 表達式 > () > ! > -a > -o
?
5、特殊條件測試
?
??? ① “:”:表示不做任何事情,退出值為0
??? ② true:表示總為真,退出值為0
??? ③ false:表示總為假,退出值為255
?
??? 舉例:
?
??? echo "Enter two numbers"
??? read x y
??? ((z=x+y))
??? if [[ z -gt 10 ]]
??? then
????? echo "x+y>10"
??? fi
??? ((x*=y))
??? ((z%=5))
??? if [[ x -le 100 || z -ne 0 ]]
??? then
????? echo "x*y<=100 or (x+y)%5!=0"
??? fi
??? echo "Your current directory is `pwd`"
??? echo "Enter a file name ->\c"
??? read name
??? if [[ -r $name && -f $name ]]
??? then
????? cat $name
??? elif [[ -d $name && -x $name ]]
??? then
????? cd $name
????? ls -l | wc -l
??? else
??? echo "Bad file name!"
??? fi
?
?
三、case語句
?
??? 語法格式為:
?
??? case 字符串 in????
??? s1) 命令??????????
??????? ...???????????
??????? 命令;;????????
??? s2) 命令??????????
??????? ...???????????
??????? 命令;;????????
??? s3) 命令??????????
??????? ...???????????
??????? 命令;;????????
??? esac??????????????
?
??? 舉例如下:
?
??? echo "Please chose either a,b or c"
??? echo "[a] print a file"
??? echo "[b] delete a file"
??? echo "[c] quit"
??? read response
??? case $response in
??? a) lp myfile;;
??? b) rm myfile;;
??? c) echo "Good bye";;
??? esac
?
??? 注意事項:
?
??? ① 一個case可以跟多條命令,最后一個命令必須以“;;”結尾
??? ② 模式字符串可以使用通配符,例如“*)”
??? ③ 如果幾個case相同處理,則用“|”隔開,表示“或”的意思
??? ④ 各個case之間不能重復,且需要考慮先后位置
??? ⑤ 以case關鍵字開頭,以esac關鍵字結尾
??? ⑥ case的退出值是最后一個命令執行的退出值,如未執行任何命令,則退出值為0
?
?