Shell編程學習之二編程
1、bash的條件測試bash
測試方法或者說測試書寫:socket
test EXPRide
[ EXPR ]函數
` EXPR `學習
例如:測試變量 User_Name 的之是否爲root測試
test $User_Name="root"
spa
[ $User_Name == "root" ]rest
[[ $User_Name == "root" ]orm
根據比較時操做數的類型,測試類型分爲:
測試類型 | 運算符 | 運算符所表明的意義 | 示例 |
×××測試 | -gt -lt -ge -le -eq -ne |
-gt 大於 -lt 小於 -ge 大於或等於 -le 小於或等於 -eq 等於 -ne 不等於 |
都是雙目運算符: [ $num -gt 3 ] test $num -ne $sum [[ $num -ne 0 ]] |
字符測試 | == =~ > < != | == 等於 >大於 < 小於 != 不等於 =~ 模式匹配 |
都是雙目運算符: [ $num == "root"] test $num > $sum [[ "$num" =~ /bin/bash$ ]] 這裏注意 =~只能用 ` `去匹配,並且=~後面的PATTERN(模式)不能使用"",''等引用字符 |
-n -z | -z 測試文件內容是否爲空,爲空時真,不爲空爲假 -n 測試文件內容是否爲不空,不空爲真,空爲假 |
單目運算符 [ -n "$file_name" ] |
|
文件測試 | -a|e -f -L|h -d -b -c -S -p -s -r -w -x -N |
-a|e 測試文件存在 -f 測試文件爲通常文件 -L|h 測試文件爲軟鏈接文件 -d 測試文件是否爲目錄 -b -c -p -S 測試文件爲塊設備、字符設備、管道文件、socket文件 -r -w -x 測試文件可讀、可寫、可執行 -s 測試文件爲空文件 -N 測試文件Mtime新於Atime |
都是單目運算符 [ -f "$file_name" ] [[ -b "$file_name" ]] test -x $file_name |
-nt -ot | file1 -nt file2 file1的Mtime新於file2的Mtime file1 -ot file2 file1的Mtime舊於file2的Mtime |
雙目運算符 [ file1 -nt "$file_name" ] [[ $file1 -ot "$file_name" ]] |
2、邏輯運算
布爾運算:布爾運算的結果只有2中:真和假。
常見的邏輯運算有:與 或 非 異或。與或很是用 && || ! 來表示。
與的邏輯關係:
假 && 任意 | 假 |
真 && 真 | 真 |
或的邏輯關係:
真 || 任意 | 真 |
假 || 假 | 假 |
非的邏輯關係:
!假 | 真 |
!真 | 假 |
異或的邏輯關係:相同爲假,不一樣爲真
3、選擇
bash中的選擇語句一般有if,case。固然if,case在大多數狀況下是能夠相互轉換的。
1)if選擇語句
一、單分支if語句:
if CONDITION;then
選擇分支
fi
二、雙分支的if語句:
if CONDITION;then
選擇分支1
else
選擇分支2
fi
三、多分支的if語句:
if CONDITION1;then
選擇分支1
elif CONDITION2;then
選擇分支2
elif CONDITION3;then
選擇分支3
...
else
選擇分支n
fi
2)case語句
語法格式:
case 變量引用 in
PATTERN1)
分支1
;;
PATTERN2)
分支2
;;
...
*)
分支n
;;
esac
PATTERN:類同於文件名通配機制,但支持使用「|」表示或者
a|b: a或者b
*:匹配任意長度的任意字符
?: 匹配任意單個字符
[]: 指定範圍內的任意單個字符
四、練習
寫一個腳本,完成以下任務,其使用形式以下所示:
script.sh {start|stop|restart|status}
其中:
若是參數爲空,則顯示幫助信息,並退出腳本;
若是參數爲start,則建立空文件/var/lock/subsys/script,並顯示「starting script successfully.」
若是參數爲stop,則刪除文件/var/lock/subsys/script,並顯示「Stop script successfully.」
若是參數爲restart,則刪除文件/var/locksubsys/script並從新建立,然後顯示「Restarting script successfully.」
若是參數爲status,那麼:
若是文件/var/lock/subsys/script存在,則顯示「Script is running...」,不然,則顯示「Script is stopped.」
說明:script.sh是腳本文件名,在建立時,其名稱能夠本身隨意定義,但若是其名稱發生變量,上/var/lock/sussys/下的文件名也要隨之而變;
[root@server scripts]# cat myhttpd #!/bin/bash # # Description: # Version: 0.0.1 # Author: Alex # Date: 2014-07-09 #判斷參數個數,若是參數小於1,則提示用法並退出 if [ $# -lt 1 ];then echo "Usage: `basename $0` {start|stop|restart|status}" exit 2 fi #判斷/var/lock/subsys是否存在,不存在則建立此目錄 if [ ! -d /var/lock/subsys ];then /bin/mkdir -p /var/lock/subsys fi if [ "$1" == "start" ];then #若是/var/lock/subsys/`basename $0`文件不存在,則建立,並顯示啓動成功;若存在則提示已啓動 [ ! -e "/var/lock/subsys/`basename $0`" ] && /bin/touch "/var/lock/subsys/`basename $0`" && echo "Starting `basename $0` successfully." \ || echo "`basename $0` is already start." elif [ "$1" == "stop" ];then #若是/var/lock/subsys/`basename $0`文件存在,則刪除,並顯示關閉成功;若不存在則顯示關閉失敗 [ -e "/var/lock/subsys/`basename $0`" ] && /bin/rm -f "/var/lock/subsys/`basename $0`" && echo "Stop myhttpd successfully." \ || echo -e "Stopping myhttpd \033[31mFAILED\033[0m." elif [ "$1" == "status" ];then #若是/var/lock/subsys/`basename $0`文件存在,顯示running;若不存在則提示stopd [ -e "/var/lock/subsys/`basename $0`" ] && echo "`basename $0` is running..." || echo "`basename $0` is stopped." else echo "Usage: `basename $0` {start|stop|restart|status}" fi
上面的腳本也能夠用case語句結合函數來實現。
# 通常狀況下,case與函數一塊兒使用的居多。 #!/bin/bash if [ $# -lt 1 ];then echo "Usage: `basename $0` {start|stop|restart|status}" exit 2 fi [ $UID -ne 0 ] && echo "permission denied." && exit 5 if [ ! -d /var/lock/subsys ];then /bin/mkdir -p /var/lock/subsys fi service_name=`basename $0` ser_path="/var/lock/subsys/$service_name" start() { if [ ! -e "$ser_path" ];then /bin/touch "$ser_path" echo "Starting $service_name successfully." else echo "$service_name is already start." fi } stop() { if [ -e "$ser_path" ];then /bin/rm -f "$ser_path" echo "Stop $service_name successfully." else echo -e "Stopping $service_name \033[31mFAILED\033[0m." fi } status() { if [ -e "$ser_path" ];then echo "$service_name is running..." else echo "$service_name is stopped." fi } other() { echo "Usage: $service_name {start|stop|restart|status}" exit 4 } case "$1" in start) start ;; stop) stop ;; status) status ;; *) other ;; esac
4、其餘
一、組合條件測試:在多個條件間實現邏輯運算
與:[ condition1 -a condition2 ]
condition1 && condition2
或:[ condition1 -o condition2 ]
condition1 || condition2
非:[ -not condition ]
! condition
二、bash編程之交互編程
read 與用戶交互進行
-p "prompt" 提示語句
-t timeout 設置超時時間
三、exit
程序退出語句,通常是 exit n 這樣使用,n是錯誤狀態值。
四、shift
一般是shift n 這樣使用,n是要踢掉的參數個數
[root@server scripts]# cat ./aboutshift #!/bin/bash echo $1 shift 2 #踢掉2個參數 echo $1 shift 3 #踢掉3個參數 echo $1 [root@server scripts]# ./aboutshift 1 2 3 4 5 6 7 8 9 10 1 3 6
而shift真正的做用是,判斷腳本參數的問題。例如:
寫一個腳本,使用形式以下所示
showifinfo.sh [-i INTERFACE|-a] [-v]
要求:
一、-i或-a不可同時使用,-i用於指定特定網卡接口,-a用於指定全部接口;
顯示接口的ip地址
二、使用-v,則表示顯示詳細信息
顯示接口的ip地址、子網掩碼、廣播地址;
三、默認表示僅使用-a選項;
#!/bin/bash # # 經過這種方法來判斷一個腳本的參數選項 verbose=0 allInterface=0 ifflag=0 while [ $# -ge 1 ]; do case $1 in -a) allInterface=1 shift 1 ;; -i) ifflag=1 interface="$2" shift 2 ;; -v) verbose=1 shift ;; *) echo "wrong option" exit 2 ;; esac done [ $ifflag -eq 1 -a $allInterface -eq 1 ] && "Usage Error." && exit 12 if [ $allInterface -eq 1 || $# -eq 0 ]; then if [ $verbose -eq 1 ]; then ifconfig | grep "inet addr:" else ifconfig | grep "inet addr:" | awk '{print $2}' fi fi if [ $ifflag -eq 1 ]; then if [ $verbose -eq 1 ]; then ifconfig $interface | grep "inet addr:" else ifconfig $interface | grep "inet addr:" | awk '{print $2}' fi fi