一、前言
在linux中,通常我們所指的腳本編程,指的是bash的腳本編程。
bash作為一種過程式的編程語言來說,它應該具備編程語言所應該具備的基本元素,即:變量,流程,函數,數組。今天我們介紹變量以及流程之一的條件判斷。
二、變量
1、初識變量
在編程語言中,編程語言有兩大種,強類型語言和弱類型語言。強類型語言中,要求變量的使用要嚴格符合定義,所有變量都必須先定義后使用。java、.NET、C++等都是強制類型定義的。與其相對應的是弱類型語言:數據類型可以被忽略的語言。它與強類型定義語言相反, 一個變量可以賦不同數據類型的值。
常見的數據類型有:
數值型:整形,浮點型,布爾型
字符型:單字符,字符串
bash屬于弱類型語言,其默認的變量類型為字符型。
2、bash中的變量
我們知道,變量可以按其數據的類型進行劃分,在bash中變量按其作用域的不同,也可以進行不同的劃分。
a) 局部變量:在bash腳本中,其作用域范圍為局部性,比如想限制變量只在某函數中起作用
b) 本地變量:在bash腳本中,其作用域范圍為整個腳本,即腳本開始到結束
c) 環境變量:系統工作使用的變量,常見的環境變量有,$PATH, $HOME, $PWD, 等等
d) 位置參數變量:用于向腳本中傳遞參數
e) 特殊變量:bash中預先定義好的具有特殊意義的比變量,如:$0, $1, $#, $@,….
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
三、第一個腳本
# vim script01.sh # 編輯如下內容 #!/bin/bash # Pragram: This is test scirpt. # Author: FengYuxiu # Version: 1.0 # History: 2015/06/29 echo "Hello World." # 保存內容并退出 # # bash -n script01.sh # bash -x script01.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 條件表達式; then command5 command6 .... else commandN fi
五、基于if的條件測試腳本
練習1、向腳本中傳遞一個0-100的數字,85以上輸出“A”,大于70小于85的輸出“B”,大于60小于70的輸出“C”,其他的輸出“D”。
#!/bin/bash # 初始化score的值 declare -i score=0 # 把參數1的值復制給score score=$1 if [ $score -ge 85 ]; then echo "Rank is A." elif [ $score -ge 70 ]; then echo "Rank is B." elif [ $score -ge 60 ]; then echo "Rank is C." else echo "Rank is D." fi
知識點補充:使用$1,$2, $N, 可以獲取腳本的參數,沒有傳遞時,獲取為空值。
$0表示執行的腳本名
$#表示腳本參數的個數
$@表示腳本的腳本的所有參數,數據結構為數組
$*表示腳本的所有參數,數據結構為字符串
練習2、在練習1的基礎上,向腳本傳遞兩個參數,參數1為用戶名,參數2為分數,顯示該學生所對應的等級。并且參數最少為2個,且第二個參數必須為數值。
#!/bin/bash # 判斷向腳本傳遞參數的個數,參數個數小于兩個,返回錯誤并結束腳本。 if [ $# -lt 2 ]; then echo "The parameter is less than 2." exit 1 fi # 判斷參數2是否為數值,數值以外,顯示錯誤,并退出腳本。 # 此處對數值沒有進行精確判斷,因此沒有過濾以0開頭的數值 if ! echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then echo "Please input like ->> $0 name score" exit 1 fi declare -i score=0 name=$1 score=$2 if [ $score -ge 85 ]; then rank=A elif [ $score -ge 70 ]; then rank=B elif [ $score -ge 60 ]; then rank=C else rank=D fi echo "${name}'s score is $rank"
練習3、驗證輸入數值的正確性,分數的范圍必須在0-100之間。
#!/bin/bash declare -i score=0 if [ $# -lt 2 ]; then echo "The parameter is less than 2." exit 1 fi if echo "$2" | grep "[[:digit:]]\{1,\}" &> /dev/null ; then if [ $2 -ge 0 -a $2 -le 100 ]; then name=$1 # 在把值復制給score變量前,用sed把前面的0都給去掉 score=$(echo $2 | sed 's/^0*//') if [ $score -ge 85 ]; then rank=A elif [ $score -ge 70 ]; then rank=B elif [ $score -ge 60 ]; then rank=C else rank=D fi echo "${name}'s score is $rank" else echo "Please enter 0 to 100 points." fi else echo "Please input like ->> $0 name score" exit 1 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 $1 in 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: (old than) 判斷文件1是否比文件2新
$file1 -et $file2: 判斷文件1是和文件是否為同一個文件的硬鏈接
八、條件判斷腳本的實戰練習
功能:向腳本傳遞兩個參數,第一個為fstab或bash,第2個參數為文件名,然后用vim打開對象文件編輯,并在用戶保存退出文件時,對保存修改后的腳本進行語法檢查。
#!/bin/bash # Pragram: This is Grammar test script. # Author: FengYuxiu # Version: 1.0 # History: 2015/07/04 # 進行參數判斷 if [ $# -lt 2 ]; then echo "Please enter an filename." exit 1 fi filename=$2 # 判斷文件是否存在 if [ ! -e $filename ]; then echo "file is not exits " read -p "Use the $filename to create new file.(yes/no): " yesno if [ ${yesno:=no} == "yes" -o $yesno == "y" ]; then touch $filename else exit 1 fi fi # 判斷文件是否為普通文件 if [ ! -f $filename ]; then echo "Please enter ASCII text." exit 1 fi case $1 in bash|sh) vim $filename # 對文件進行語法檢查,并把錯誤信息保存到errmsg變量中 errmsg=$(bash -n $filename 2>&1) if [ -n "$errmsg" ]; then clear echo "$errmsg" read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then vim $filename fi fi # 因為是腳本,所以加上執行權限 chmod u+x $filename ;; fstab) vim $filename # 用mount -a 對掛載文件進行語法檢測 errmsg=$(mount -a 2>&1) if [ -n "$errmsg" ]; then clear echo "$errmsg" read -t 15 -p "Syntax error.Whether to modify.(yes/no): " isedit if [ ${isedit:no} == "yes" -o $isedit == "y" ]; then vim $filename fi fi ;; *) echo "Usage $0 {bash|sh|fstab} filename." exit 1 esac clear echo "$filename is save success."
1、執行腳本
2、故意使腳本語法錯誤,保存并退出
3、提示語法錯誤,并提示是否修改,輸入yes回到vim界面修改,輸入no結束,此處輸入yes返回vim
4、修改完成,保存并退出
5、顯示成功信息
注意:此處的腳本只用到條件判斷語句,沒有用到循環,所以語法判斷只能進行一次。
好了,以上的整理如有遺漏或錯誤,還請大神賜教。
原創文章,作者:封于修,如若轉載,請注明出處:http://www.www58058.com/5977