1. 程式人生 > 實用技巧 >BASH程式設計基礎之變數、條件判斷

BASH程式設計基礎之變數、條件判斷

一、前言

linux中,通常我們所指的指令碼程式設計,指的是bash的指令碼程式設計。

bash作為一種過程式的程式語言來說,它應該具備程式語言所應該具備的基本元素,即:變數,流程,函式,陣列。今天我們介紹變數以及流程之一的條件判斷。

二、變數

1、初識變數

在程式語言中,程式語言有兩大種,強型別語言和弱型別語言。

強型別語言中,要求變數的使用要嚴格符合定義,所有變數都必須先定義後使用。java.NETC++等都是強制型別定義的。

與其相對應的是弱型別語言:資料型別可以被忽略的語言。它與強型別定義語言相反, 一個變數可以賦不同資料型別的值。

常見的資料型別有:
數值型:×××,浮點型,布林型


字元型:單字元,字串

bash屬於弱型別語言,其預設的變數型別為字元型。

2bash中的變數

我們知道,變數可以按其資料的型別進行劃分,在bash中變數按其作用域的不同,也可以進行不同的劃分。

a) 區域性變數:在bash指令碼中,其作用域範圍為區域性性,比如想限制變數只在某函式中起作用

b) 本地變數:在bash指令碼中,其作用域範圍為整個指令碼,即指令碼開始到結束

c) 環境變數:系統工作使用的變數,常見的環境變數有,$PATH, $HOME, $PWD, 等等

d) 位置引數變數:用於向指令碼中傳遞引數

e) 特殊變數:bash中預先定義好的具有特殊意義的比變數,如:$0, $1, $#, [email protected]

,….

3bash中的變數的定義和使用

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

wKioL1WjtWvSctPDAABmXFOKBYw528.jpg

顯示執行過程,並執行成功,顯示echo中的內容。

其中,在bash指令碼中有一些規定好的規則
1
、第一行為固定格式,#!/bin/bash,表示這是一個bash的指令碼,而不是一個普通的文字檔案,讓bash直譯器執行以下語句。

2#為註釋行,除了第一行中的#!/bin/bash

3、執行bash指令碼的方法有兩種,一個是給指令碼加上執行許可權,並指明執行路徑,另一個是直接向bash命令傳遞指令碼名,讓bash解釋執行指令碼的內容

4bash-n SCRIPT_NAME.sh檢查指令碼的是否存在語法錯誤

5bash-x SCRIPT_NAME.sh檢視指令碼的執行過程,用於指令碼排錯

四、指令碼的條件測試

說起條件測試,我們就想起布林型,當然,測試的結果返回值只有兩種,真或者假。其中在bash0表示真,0以外表示假。

1、整數的測試:(整數AB)

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 == BA = B:字串等值比較

A !=B :不等於

-z A:判斷A是否為空,空為真,不空為假

-n A:判斷A是否為不空,不空為真,空為假

3、條件測試的方法:

a) test測試表達式

b) [測試表達式] : []與於測試表達式之間必須要有一個半形空格,否則語法錯誤

c) [[測試表達式]] :等同於[測試表達式],但有些特殊場合需要用到[[測試表達式]]

4、條件測試方法在指令碼中的使用

if條件表示式;then
command1
command2
…..
fi

wKiom1Wjs5SDgJ8xAABkmZ_LCMQ664.jpg

當然,if的條件表示式可以巢狀,也可以進行多個條件判斷

if條件表示式;then
command1
command2
if條件表示式;then
command3
command4
…..
fi
elif
command5
command6
….
else
commandN
fi

wKioL1WjtWzC6p_OAADexJS1I7A541.jpg

五、基於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

wKiom1Wjs5WjZ6SkAAFDDin-OqA442.jpg

知識點補充:使用$1,$2, $N, 可以獲取指令碼的引數,沒有傳遞時,獲取為空值。

$0表示執行的指令碼名


$#表示指令碼引數的個數


[email protected]表示指令碼的指令碼的所有引數,資料結構為陣列


$*表示指令碼的所有引數,資料結構為字串

wKioL1WjtWzibKovAAHpvpIS9EE156.jpg

練習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"

wKiom1Wjs5WClYkXAAHbk9Bf6wo890.jpg

練習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

wKioL1WjtWzgpEmpAAKUsASUHg8509.jpg

六、基於case的條件測試指令碼

case其實也可以說是簡潔版的多跟支if語句。它的語法格式如下:

case
變數引用
in
PATTERN1)

分支
1
;;
PATTERN2)

分支
2
;;
……
*)

分支
n
;;
esca

wKioL1WjtW2zG7iLAACdsSDdJGA397.jpg

PATTERN表示的是匹配條件,具體格式如下:

*:表示任意長度字元

?:任意單個字元

[]:指定範圍內的任意單個字元

A|BAB

練習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

wKiom1Wjs5bTCw6kAAIVLVmOXCI886.jpg

wKioL1WjtW2TMobEAAD6fLk3B0A076.jpg

wKiom1Wjs5agD5BmAAJywIRP5HM145.jpg

wKiom1Wjs5aSThf3AADVukk_8RU530.jpg

wKioL1WjtW2DgV-MAABphoq-NGk535.jpg

七、條件測試知識擴充套件

1、字串測試:

“$A” =~ PATTERN:如果變數中儲存的字串能被PATTERN匹配,則為真,否則為假

2、檔案測試:

-e $file :判斷檔案是否存在,存在為真

-f $file:判斷檔案是否存在,且為普通檔案,滿足條件為真

-d $file:判斷是否存在且為為目錄

-b $file:判斷是否存在且為塊裝置

-c $file:判斷是否存在且為字元裝置

-S $file:判斷是否存在且為套接字裝置

-p $file:判斷是否存在且為管道裝置

-L $file:判斷是否存在且為符號連結檔案

-rwx $file:判斷使用者是否對此檔案有讀,寫,執行許可權

-ugk $file:判斷檔案是否擁有suidsgid, 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

wKioL1WjtW6ivVKAAAJPfviitCY256.jpg

八、條件判斷指令碼的實戰練習

功能:向指令碼傳遞兩個引數,第一個為fstabbash,第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、執行指令碼

wKiom1Wjtv3imAdTAABYmLZUiFY967.jpg

2、故意使指令碼語法錯誤,儲存並退出

wKiom1Wjs5nR3uigAAAwDczk7F4117.jpg

3、提示語法錯誤,並提示是否修改,輸入yes回到vim介面修改,輸入no結束

wKioL1WjtXCAqrU0AAB-Xmc5OOA603.jpg

4、修改完成,儲存並退出

wKiom1Wjs5mRwrCEAAAoOzqlbWc626.jpg

5、顯示成功資訊

wKioL1WjtXCiH82jAABJo3cUvds300.jpg

注意:此處的指令碼只用到條件判斷語句,沒有用到迴圈,所以語法判斷只能進行一次。

轉載於:https://blog.51cto.com/fengyuxiu/1674209