1. 程式人生 > >bash腳本之case語句應用,while、until和select循環應用及其示例

bash腳本之case語句應用,while、until和select循環應用及其示例

bash腳本

bash腳本編程:

case選擇分支結構:

case: case 詞 in [模式 [| 模式]...) 命令 ;;]... esac


在腳本中使用case的結構:

case ${VAR_NAME} in

PATTERN1)

COMMAND

...

;;

PATTERN2)

COMMAND

...

;;

...

esac

擴展:

case ${VAR_NAME} in

PATTERN1)

COMMAND

...

;;

PATTERN2)

COMMAND

...

;;

*) //‘*)’在這裏是如果不是模式1也不是模式2時,就使用‘*)’後的命令

COMMAND

...

;;

esac


PATTERN(模式)可以是下列幾類字符:

1.普通文本字符

2.Globbing風格的通配符

*:任意長度的任意字符

?:任意單個字符

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

[^]:指定範圍外的任意單個字符

3.| 或字符,實現‘或’操作


寫一個腳本:

判斷用戶利用腳本刪除文件時,是否執行刪除操作;


#!/bin/bash

#判斷用戶利用腳本刪除文件時,是否執行刪除操作(case選擇分支結構);

#判斷用戶是否存在,存在就執行是否刪除文件的操作,不存在就顯示文件不存在;

if [ -a $1 ];then

echo -e "\033[5;1;32mDanger!\033[1;31mAre you sure to delete it ? [ yes or no ] \033[0m"

#與用戶交互使用read命令,-t選項顯示5秒

read -t 5 CHOICE

#檢測CHOICE的值是否存在,如果不存在就默認顯示為no

[ -z $CHOICE ] && CHOICE=no

#case選擇分支結構,如果$CHOICE的值是yes就執行刪除命令,no則顯示"Right choice."

case $CHOICE in

yes)

rm -rf $1

;;

no)

echo "Right choice."

;;

esac

else

echo "$1 does not exist."

fi


#回收變量

unset CHOICE


#!/bin/bash

#判斷用戶利用腳本刪除文件時,是否執行刪除操作(if循環結構);

#判斷用戶是否存在,存在就執行是否刪除文件的操作,不存在就顯示文件不存在;

if [ -e $1 ] ; then

echo -e "\033[5;1;31mDanger!\033[0m\033[1;31mAre you sure to delete it? [yes or no] \033[0m"

#與用戶交互使用read命令,-t選項顯示5秒

read -t 5 CHOICE

#檢測CHOICE的值是否存在,如果不存在就默認顯示為no

[ -z $CHOICE ] && CHOICE=no

#if多分支執行結構,如果是yes就執行刪除命令,no則顯示"Right choice."

if [ "$CHOICE" == 'yes' ] ; then

rm -rf $1

elif [ "$CHOICE" == 'no' ] ; then

echo "Right choice."

fi

else

echo "$1 does not exist."

fi


#回收變量

unset CHOICE



if的多分支結構和case的選擇分支結構的異同:

相同點:

1.判斷的條件為真時,才會執行對應分支中的語句命令;條件為假跳過不執行;

2.都可以設置默認分支語句,即所有給定的條件都為假時才會執行的語句。

不同點:

1.if是根據命令的執行狀態返回值的真或假是否該執行某個分支中的語句;case一般是根據變量中所保存的值與指定的模式匹配的結果的真或假來判斷是否執行某個分支中的語句;

2.if的每個分支中無須單獨的結束標記,case的每個分支都必須以‘;;’結束;


示例:

設置編寫管理用戶賬戶的腳本,利用case語句+for循環,同時接受創建用戶和刪除用戶的操作:

#!/bin/bash

#設置編寫管理用戶賬戶的腳本,利用case語句+for循環,同時接受創建用戶和刪除用戶的操作:

#設置用戶給定的參數值至少要有1個,否則輸出如下的信息,返回值為5;

if [ $# -lt 1 ] ; then

echo -e "Usage: $(basename $0) options... USERLIST\n"

echo -e " Options: "

echo -e " -a, --add: \vAdd some users from USERLIST."

echo -e " -d, --delete: \vDelete some users from USERLIST."

echo -e " -h, --help: \vPrint help informationn."

echo -e " -v, --verbose: \vPrint more informationn about manage users."

echo

echo -e " USERLIST FORMAT: "

echo -e " USERNAME1,USERNAME2,...,USERNAMEN"

exit 5

fi


#定義三個開關量,當0變為1的時候,說明就有這個操作了;

ADDUSER=0

DELUSER=0

DEBUG=0


#有多少個參數就執行for循環多少次,

for I in $(seq $#) ; do

#如果參數不為0,就利用case結構執行判斷用戶給定的第一個參數的內容,如果給定的內容不在case設定的範圍內,就輸出幫助文檔;

if [ $# -ne 0 ] ;then

case $1 in

-h|--help)

echo -e "Usage: $(basename $0) options... USERLIST\n"

echo -e " Options: "

echo -e " -a, --add: \vAdd some users from USERLIST"

echo -e " -d, --delete: \vDelete some users from USERLIST"

echo -e " -h, --help: \vPrint help informationn"

echo -e " -v, --verbose: \vPrint more informationn about manage users."

echo

echo -e " USERLIST FORMAT: "

echo -e " USERNAME1,USERNAME2,...,USERNAMEN"

#如果用戶輸入-h選項,返回值就為0,表明之後的命令不會再執行;

exit 0

;;

-v|--verbose)

#當DEBUG為1的時候就顯示之後的信息;

DEBUG=1

#把-v選項shift掉;

shift

;;

-a|--add)

ADDUSERLIST=$2

ADDUSER=1

shift 2

;;

-d|--delete)

DELUSERLIST=$2

DELUSER=1

shift 2

;;

*)

echo -e "Usage: $(basename $0) options... USERLIST\n"

echo -e " Options: "

echo -e " -a, --add: \vAdd some users from USERLIST"

echo -e " -d, --delete: \vDelete some users from USERLIST"

echo -e " -h, --help: \vPrint help informationn"

echo -e " -v, --verbose: \vPrint more informationn about manage users."

echo

echo -e " USERLIST FORMAT: "

echo -e " USERNAME1,USERNAME2,...,USERNAMEN"

exit 6

;;

esac

fi

done


#如果$ADDUSER等於1,證明我們添加了-a選項,進而執行之後的命令;

if [ $ADDUSER -eq 1 ] ; then

#利用for循環,添加多個用戶,多個用戶之間用“,”分隔,為了更好的執行命令,在這裏用空格代替“,”從而實現添加多個用戶的操作;

for J in $(echo $ADDUSERLIST | tr ',' ' ') ; do

#在添加用戶之前,首先要確定用戶的存在,如果用戶不存在就添加用戶,存在就輸出用戶已存在;

if ! id $J &> /dev/null ; then

useradd $J &> /dev/null

echo $J | passwd --stdin $J &> /dev/null

#當DEBUG為1的時候就顯示之後的信息,意味著添加了-v選項;

[ $DEBUG -eq 1 ] && echo "Create user $J successfully."

else

echo "$J exist already."

fi

done

fi


#如果$DELUSER等於1,證明我們添加了-d選項,進而執行之後的命令;

if [ $DELUSER -eq 1 ] ; then

#利用for循環,刪除多個用戶,多個用戶之間用“,”分隔,為了更好的執行命令,在這裏用空格代替“,”從而實現刪除多個用戶的操作;

for J in $(echo $DELUSERLIST | tr ',' ' ') ; do

#在刪除用戶之前,首先要確定用戶的存在,如果用戶已經存在就刪除用戶,否則顯示用戶不存在;

if id $J &> /dev/null ; then

userdel -r $J &> /dev/null

#當DEBUG為1的時候就顯示之後的信息,意味著添加了-v選項;

[ $DEBUG -eq 1 ] && echo "Delete user $J finished."

else

echo "$J does not exist yet."

fi

done

fi


#記得回收內存空間

unset ADDUSER DELUSER DEBUG I J



while循環結構:

while: while 命令; do 命令; done


在腳本中可以寫成下列結構:

while CONDITION ;do

COMMANDS

done


while循環進入循環的條件:CONDITION邏輯判斷結果為真;

while循環退出循環的條件:CONDITION邏輯判斷結果為假;



until循環結構:

until: until 命令; do 命令; done


在腳本中可以寫成下列結構:

until CONDITION ;do

COMMANDS

done


until循環進入循環的條件:CONDITION邏輯判斷結果為假;

until循環退出循環的條件:CONDITION邏輯判斷結果為真;


註意:

1.while CONDITION 相當於 until ! CONDITION

2.while和until循環結構中,沒有變量自增或自減的變化方法,因此需要使用語句手動給出變量的變化方式;


例子:

寫一個腳本:使用while或until循環,計算100以內的整數和

#!/bin/bash

#until循環

#定義I初值為0

declare -i I=0

#當I的值小於等於100的時候執行累加和命令,直到I的值大於100的時候就結束循環;

until [ $I -gt 100 ];do

let SUM+=$I

let I++

done

#輸出累加結果;

echo $SUM


#while循環

#定義J的初值為0

declare -i J=0

#當J的值小於等於100時執行累加命令,當J的值超出100時結束當前循環;

while [ $J -le 100 ];do

let SUM1+=$J

let J++

done

#輸出累加結果;

echo -e "\n$SUM1"


#別忘了回收變量,浪費內存空間是不好的哦!

unset I J SUM SUM1



循環控制語句:

continue: continue [n]

繼續 for、while、或 until 循環。 提前結束第n層當前循環,直接進入下一輪條件判斷,如果條件判斷結果仍然滿足循環進入條件,則開啟下一輪循環;

繼續當前 FOR、WHILE 或 UNTIL 循環的下一步。

如果指定了 N, 則繼續當前的第 N 重循環。

退出狀態:

退出狀態為 0 除非 N 不大於或等於1。


示例:

計算100以內奇數和;

#!/bin/bash

#定義I初值為0

declare -i I=0

while [ $I -le 100 ];do

#如果I的值取模後的值等於0就加1,如果不等於就跳過直接執行下一輪的命令

if [ $[I%2] -eq 0 ];then

let I++

continue

fi

let SUM+=$I

let I++

done


#別忘了回收變量,浪費內存空間是不好的哦!

unset I SUM

echo $SUM



break: break [n]

退出 for、while、或 until 循環

提前結束第n層循環,而且不再進行後續循環;

退出一個 FOR、WHILE 或 UNTIL 循環。如果指定了N,則打破N重

循環

退出狀態:

退出狀態為0除非 N 不大於或等於 1。



while和until的兩種特殊循環方法:

1.無限循環方法:

while true ; do

COMMANDS

done


until false ; do

COMMANDS

done



註意:在此類循環結構中,需要適當的添加continue或break控制語句,以使得無限循環可控;


例子:

guess number:

#!/bin/bash

#本腳本取100以內的整數,猜出取數的隨機數;

#設定隨機取值範圍1-100,RANDOM內數字取模後範圍在100以內,再加1,表示這次腳本隨機取值範圍在1-100;

NUMBER=$[RANDOM%100+1]

while true ; do

#與用戶交互,讓用戶輸入一個整數;

read -p "Input a number: " INPTNUM

#讓用戶輸入的整數與隨機取出的數比較,三種情況對應顯示回應;

if [ $INPTNUM -gt $NUMBER ] ; then

echo "Too big"

elif [ $INPTNUM -lt $NUMBER ] ; then

echo "Too small"

else

echo "Yes! you WIN. That's $NUMBER."

#break命令打破死循環;

break

fi

done


#回收變量

unset NUMBER INPUTNUM


#!/bin/bash

#本腳本取100以內的整數,猜出取數的隨機數;

#設定隨機取值範圍1-100,RANDOM內數字取模後範圍在100以內,再加1,表示這次腳本隨機取值範圍在1-100;

NUMBER=$[RANDOM%100+1]

until false ; do

#與用戶交互,讓用戶輸入一個整數;

read -p "Input a number: " INPTNUM

#讓用戶輸入的整數與隨機取出的數比較,三種情況對應顯示回應;

if [ $INPTNUM -gt $NUMBER ] ; then

echo "Too big"

elif [ $INPTNUM -lt $NUMBER ] ; then

echo "Too small"

else

echo "Yes! you WIN. That's $NUMBER."

#break命令打破死循環;

break

fi

done


#回收變量

unset NUMBER INPUTNUM



2.實現遍歷功能的while和until循環結構:

while read LINES;do

COMMANDS

done < /PATH/FROM/SOMEFILE


until ! read LINES;do

COMMANDS

done < /PATH/FROM/SOMEFILE


註意:在做遍歷循環時,建議使用for;



select循環結構:

select: select NAME [in 詞語 ... ;] do 命令; done

從列表中選取詞並且執行命令。(類似於for循環的遍歷)


select循環也是一種遍歷列表的方式創建一個可視化菜單,每個列表都有一個數字編號與之對應,供用戶選擇使用;而用戶只需要選擇其編號即可;


select是一種默認無限循環結構,因此,必須在循環體中為select提供退出循環的條件,通常可以使用break或exit命令實現;


通常情況下,select循環會和case一起使用,以進行合理的取值判斷;


在腳本中實現的格式:

select VAR_NAME in LIST ; do

COMMANDS

done


寫一個腳本,顯示以/bin/bash為默認shell的用戶的id信息:

#!/bin/bash

#本腳本顯示以/bin/bash為默認shell的用戶的id信息:

#awk命令獲取/etc/passwd下以“:”分隔以/bin\/bash為結尾的用戶的id;

select I in $(awk -F : '/\/bin\/bash$/{print $1}' /etc/passwd) quit ; do

#如果I的值為quit直接執行退出命令,否則就顯示用戶的id信息;

case $I in

quit)

exit

;;

*)

echo "The UID of $I is $(id -u $I)"

;;

esac

done

#回收變量;

unset I


bash腳本之case語句應用,while、until和select循環應用及其示例