BASH程式設計基礎之變數、條件判斷
一、前言
在linux中,通常我們所指的指令碼程式設計,指的是bash的指令碼程式設計。
bash作為一種過程式的程式語言來說,它應該具備程式語言所應該具備的基本元素,即:變數,流程,函式,陣列。今天我們介紹變數以及流程之一的條件判斷。
二、變數
1、初識變數
在程式語言中,程式語言有兩大種,強型別語言和弱型別語言。
強型別語言中,要求變數的使用要嚴格符合定義,所有變數都必須先定義後使用。java、.NET、C++等都是強制型別定義的。
與其相對應的是弱型別語言:資料型別可以被忽略的語言。它與強型別定義語言相反, 一個變數可以賦不同資料型別的值。
常見的資料型別有:
數值型:×××,浮點型,布林型
字元型:單字元,字串
bash屬於弱型別語言,其預設的變數型別為字元型。
2、bash中的變數
我們知道,變數可以按其資料的型別進行劃分,在bash中變數按其作用域的不同,也可以進行不同的劃分。
a) 區域性變數:在bash指令碼中,其作用域範圍為區域性性,比如想限制變數只在某函式中起作用
b) 本地變數:在bash指令碼中,其作用域範圍為整個指令碼,即指令碼開始到結束
c) 環境變數:系統工作使用的變數,常見的環境變數有,$PATH, $HOME, $PWD, 等等
d) 位置引數變數:用於向指令碼中傳遞引數
e) 特殊變數:bash中預先定義好的具有特殊意義的比變數,如:$0, $1, $#, [email protected]
3、bash中的變數的定義和使用
a) 宣告某變數為區域性變數:local VAR_NAME=VALUE
b) 宣告某變數為本地變數:
I) 不指定型別,預設型別為字元型 : VAR_NAEM=VALUE
II) 定義資料型別為整數型:let VAR_NAME=VALUE 或 declare -i VAR_NAME=VALUE
III) 宣告某變數為環境變數:export VAR_NAME=VALUE 或 declare -x VAR_NAME=VALUE
三、第一個指令碼
#vimscript01.sh #編輯如下內容 #!/bin/bash #Pragram:Thisistestscirpt. #Author:FengYuxiu #Version:1.0 #History:2015/07/13 echo"HelloWorld." #儲存內容並退出 # #bash-nscript01.sh #bash-xscript01.sh
顯示執行過程,並執行成功,顯示echo中的內容。
其中,在bash指令碼中有一些規定好的規則
1、第一行為固定格式,#!/bin/bash,表示這是一個bash的指令碼,而不是一個普通的文字檔案,讓bash直譯器執行以下語句。
2、#為註釋行,除了第一行中的#!/bin/bash
3、執行bash指令碼的方法有兩種,一個是給指令碼加上執行許可權,並指明執行路徑,另一個是直接向bash命令傳遞指令碼名,讓bash解釋執行指令碼的內容
4、bash-n SCRIPT_NAME.sh檢查指令碼的是否存在語法錯誤
5、bash-x SCRIPT_NAME.sh檢視指令碼的執行過程,用於指令碼排錯
四、指令碼的條件測試
說起條件測試,我們就想起布林型,當然,測試的結果返回值只有兩種,真或者假。其中在bash中0表示真,0以外表示假。
1、整數的測試:(整數A和B)
A -gt B: A大於B
A -lt B: A小於B
A -eq B: A等於B
A -ge B: A大於等於B
A -le B: A大於等於B
A -ne B: A不等於B
2、字串測試:(字串A和字串B)
A == B或A = B:字串等值比較
A !=B :不等於
-z A:判斷A是否為空,空為真,不空為假
-n A:判斷A是否為不空,不空為真,空為假
3、條件測試的方法:
a) test測試表達式
b) [測試表達式] : []與於測試表達式之間必須要有一個半形空格,否則語法錯誤
c) [[測試表達式]] :等同於[測試表達式],但有些特殊場合需要用到[[測試表達式]]
4、條件測試方法在指令碼中的使用
if條件表示式;then
command1
command2
…..
fi
當然,if的條件表示式可以巢狀,也可以進行多個條件判斷
if條件表示式;then command1 command2 if條件表示式;then command3 command4 ….. fi elif command5 command6 …. else commandN fi
五、基於if的條件測試指令碼
練習1、向指令碼中傳遞一個0-100的數字,85以上輸出“A”,大於70小於85的輸出“B”,大於60小於70的輸出“C”,其他的輸出“D”。
#!/bin/bash #初始化score的值 declare-iscore=0 #把引數1的值複製給score score=$1 if[$score-ge85];then echo"RankisA." elif[$score-ge70];then echo"RankisB." elif[$score-ge60];then echo"RankisC." else echo"RankisD." fi
知識點補充:使用$1,$2, $N, 可以獲取指令碼的引數,沒有傳遞時,獲取為空值。
$0表示執行的指令碼名
$#表示指令碼引數的個數
[email protected]表示指令碼的指令碼的所有引數,資料結構為陣列
$*表示指令碼的所有引數,資料結構為字串
練習2、在練習1的基礎上,向指令碼傳遞兩個引數,引數1為使用者名稱,引數2為分數,顯示該學生所對應的等級。並且引數最少為2個,且第二個引數必須為數值。
#!/bin/bash #判斷向指令碼傳遞引數的個數,引數個數小於兩個,返回錯誤並結束指令碼。 if[$#-lt2];then echo"Theparameterislessthan2." exit1 fi #判斷引數2是否為數值,數值以外,顯示錯誤,並退出指令碼。 #此處對數值沒有進行精確判斷,因此沒有過濾以0開頭的數值 if!echo"$2"|grep"[[:digit:]]\{1,\}"&>/dev/null;then echo"Pleaseinputlike->>$0namescore" exit1 fi declare-iscore=0 name=$1 score=$2 if[$score-ge85];then rank=A elif[$score-ge70];then rank=B elif[$score-ge60];then rank=C else rank=D fi echo"${name}'sscoreis$rank"
練習3、驗證輸入數值的正確性,分數的範圍必須在0-100之間。
#!/bin/bash declare-iscore=0 if[$#-lt2];then echo"Theparameterislessthan2." exit1 fi ifecho"$2"|grep"[[:digit:]]\{1,\}"&>/dev/null;then if[$2-ge0-a$2-le100];then name=$1 #在把值複製給score變數前,用sed把前面的0都給去掉 score=$(echo$2|sed's/^0*//') if[$score-ge85];then rank=A elif[$score-ge70];then rank=B elif[$score-ge60];then rank=C else rank=D fi echo"${name}'sscoreis$rank" else echo"Pleaseenter0to100points." fi else echo"Pleaseinputlike->>$0namescore" exit1 fi
六、基於case的條件測試指令碼
case其實也可以說是簡潔版的多跟支if語句。它的語法格式如下:
case 變數引用 in PATTERN1) 分支 1 ;; PATTERN2) 分支 2 ;; …… *) 分支 n ;; esca
PATTERN表示的是匹配條件,具體格式如下:
*:表示任意長度字元
?:任意單個字元
[]:指定範圍內的任意單個字元
A|B:A或B
練習1、寫一個指令碼,向指令碼傳遞一個引數,如cpu,mem,idisk(表示disk info),udisk(表示disk usage),顯示相應引數所對應的資訊。
#!/bin/bash case$1in cpu) lscpu ;; mem) free ;; idisk) fdisk-l/dev/sd[a-z] ;; udisk) df-h ;; *) echo"Usage:$0{cpu|mem|idisk|udisk}" ;; esac
七、條件測試知識擴充套件
1、字串測試:
“$A” =~ PATTERN:如果變數中儲存的字串能被PATTERN匹配,則為真,否則為假
2、檔案測試:
-e $file :判斷檔案是否存在,存在為真
-f $file:判斷檔案是否存在,且為普通檔案,滿足條件為真
-d $file:判斷是否存在且為為目錄
-b $file:判斷是否存在且為塊裝置
-c $file:判斷是否存在且為字元裝置
-S $file:判斷是否存在且為套接字裝置
-p $file:判斷是否存在且為管道裝置
-L $file:判斷是否存在且為符號連結檔案
-r,w,x $file:判斷使用者是否對此檔案有讀,寫,執行許可權
-u,g,k $file:判斷檔案是否擁有suid,sgid, sticky的許可權
-O,-G$file:判斷當前使用者是否為此檔案的屬主,屬組
$file1 -nt $file2:(new than)判斷檔案1是否比檔案2新
$file1 -ot $file2:(oldthan)判斷檔案1是否比檔案2新
$file1 -et $file2: 判斷檔案1是和檔案是否為同一個檔案的硬連結
#!/bin/bash file=$1 if[$#-ge1];then if[-L$file];then echo"Thisissymboliclinkfile." elif[-d$file];then echo"Thisisdirectory." elif[-f$file];then echo"Thisiscommonfile." elif[-b$file];then echo"Thisisblockdevice." elif[-c$file];then echo"Thisischaracterdevice." else echo"Unabletoidentify." fi else echo"Pleaseenteraparameter." fi
八、條件判斷指令碼的實戰練習
功能:向指令碼傳遞兩個引數,第一個為fstab或bash,第2個引數為檔名,然後用vim開啟物件檔案編輯,並在使用者儲存退出檔案時,對儲存修改後的指令碼進行語法檢查。
#!/bin/bash #Pragram:ThisisGrammartestscript. #Author:FengYuxiu #Version:1.0 #History:2015/07/13 #進行引數判斷 if[$#-lt2];then echo"Pleaseenteranfilename." exit1 fi filename=$2 #判斷檔案是否存在 if[!-e$filename];then echo"fileisnotexits" read-p"Usethe$filenametocreatenewfile.(yes/no):"yesno if[${yesno:=no}=="yes"-o$yesno=="y"];then touch$filename else exit1 fi fi #判斷檔案是否為普通檔案 if[!-f$filename];then echo"PleaseenterASCIItext." exit1 fi case$1in bash|sh) vim$filename #對檔案進行語法檢查,並把錯誤資訊儲存到errmsg變數中 errmsg=$(bash-n$filename2>&1) if[-n"$errmsg"];then clear echo"$errmsg" read-t15-p"Syntaxerror.Whethertomodify.(yes/no):"isedit if[${isedit:no}=="yes"-o$isedit=="y"];then vim$filename fi fi #因為是指令碼,所以加上執行許可權 chmodu+x$filename ;; fstab) vim$filename #用mount-a對掛載檔案進行語法檢測 errmsg=$(mount-a2>&1) if[-n"$errmsg"];then clear echo"$errmsg" read-t15-p"Syntaxerror.Whethertomodify.(yes/no):"isedit if[${isedit:no}=="yes"-o$isedit=="y"];then vim$filename fi fi ;; *) echo"Usage$0{bash|sh|fstab}filename." exit1 esac clear echo"$filenameissavesuccess."
1、執行指令碼
2、故意使指令碼語法錯誤,儲存並退出
3、提示語法錯誤,並提示是否修改,輸入yes回到vim介面修改,輸入no結束
4、修改完成,儲存並退出
5、顯示成功資訊
注意:此處的指令碼只用到條件判斷語句,沒有用到迴圈,所以語法判斷只能進行一次。
轉載於:https://blog.51cto.com/fengyuxiu/1674209