shell腳本中的迴圈選擇語句用法詳解及實例。包括if、case、for、while、until、select、continue、break、shift、trap等。 ...
前言
在我們使用linux的過程中,腳本可以給我們省很多時間和精力,比如,我們要定期備份一些文件,如果我們純手工去操作的話,每到一個時間段我們就要去進行備份的操作,如果某一次我們在乾其他事情的時候,把這件事情忘了那可怎麼辦╮(╯﹏╰)╭這個時候,我們就可以把需要執行的備份命令放在一個腳本裡面,通過一些語句去判斷是否符合我們執行命令的條件,實現自動化0.0這樣不就省時省心很多啦~老闆再也不用擔心我忘記備份ヽ( ̄▽ ̄)ノ那麼,接下來,小編就來分享一下腳本的語法及實例。
一、條件選擇、判斷(if、case)
1.1 if語句用法及實例
當我們在腳本中遇到需要判斷的時候,我們就可以用if語句來實現。具體的語法如下:
- 單分支
if 判斷條件;then
條件為真的分支代碼
fi
- 雙分支
if 判斷條件; then
條件為真的分支代碼
else
條件為假的分支代碼
fi
- 多分支
if 判斷條件1; then
條件為真的分支代碼
elif 判斷條件2; then
條件為真的分支代碼
elif 判斷條件3; then
條件為真的分支代碼
else
以上條件都為假的分支代碼
fi
在多分支中,系統會逐條判斷你寫入的條件,第一次遇到“真”條件時,執行該分支,而後結束整個if語句。
註意:1、if和fi是成對出現的
2、if語句可以嵌套。
Example:
1)判斷兩個數字的大小
1 #!/bin/bash 2 #定義變數 3 read -p "Please input the first num:" num1 4 read -p "Please input the second num:" num2 5 #判斷數字是否符合標準 6 if [[ $num1 =~ ^[0-9]+$ && $num2 =~ ^[0-9]+$ ]];then 7 # 判斷兩個數字的大小並輸出判斷結果 8 if [ $num1 -lt $num2 ];then 9 echo "The num2 is biger than the num1" 10 elif [ $num1 -eq $num2 ];then 11 echo "Two numbers equal" 12 else 13 echo "The num1 is biger than the num2" 14 fi 15 else 16 echo "Please enter the correct number" 17 fi 18 19 #刪除變數 20 unset num1 num2
2)編寫腳本/root/bin/createuser.sh,實現如下功能:使用一個用戶名做為參數,如果指定參數的用戶存在,就顯示其存在,否則添加之;顯示添加的用戶的id號等信息
1 #!/bin/bash 2 #定義變數 3 read -p "請輸入一個用戶名:" name 4 #判斷用戶名是否存在 5 if `id $name &> /dev/null`;then 6 # 若存在,則輸出ID等信息 7 echo "用戶存在,用戶的ID信息為:`id $name`" 8 else 9 # 若不存在,則添加用戶,設置密碼為隨機8位,下次登錄時提示修改密碼,同時顯示ID等信息 10 passwd=`cat /dev/urandom |tr -cd [:alpha:] |head -c8` 11 `useradd $name &> /dev/null` 12 `echo "$passwd" | passwd --stdin $name &> /dev/null` 13 echo "用戶名:$name 密碼: $passwd" >> user.txt 14 `chage -d 0 $name` 15 echo "用戶已添加,用戶的ID信息為:`id $name` 密碼為:$passwd" 16 fi 17 18 #刪除變數 19 unset name passwd
1.2 case用法及實例
當涉及到多個條件匹配的時候,我們用if可能就很麻煩了,這個時候,我們就可以用case來編寫這個腳本。case的具體語法如下:
case 變數引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
預設分支
;;
esac
註意:1、case每一個分支後,都是以兩個“;”結尾的(最後一個可以省略)
2、case和esac是成對出現的
Example:
1)編寫一個腳本,提示用戶輸入信息,判斷其輸入的是yes或no或其他信息。
1 #!/bin/bash 2 #定義變數 3 read -p "Yue ma?(yes or no):" ANS 4 #把變數中的大寫轉換為小寫 5 ans=`echo "$ANS" |tr [[:upper:]] [[:lower:]] ` 6 #判斷輸入的信息是什麼並輸出結果 7 case $ans in 8 yes|y) 9 echo "see you tonight" 10 ;; 11 no|n) 12 echo "sorry,I have no time" 13 ;; 14 *) 15 echo "what’s your means?" 16 ;; 17 esac 18 19 #刪除變數 20 unset ANS ans
2)編寫腳本/root/bin/filetype.sh,判斷用戶輸入文件路徑,顯示其文件類型(普通,目錄,鏈接,其它文件類型)
1 #!/bin/bash 2 read -p "請輸入一個文件路徑:" file 3 #判斷文件是否存在 4 `ls $file &> /dev/null` 5 #若存在,判斷文件類型並輸出 6 if [ $? -eq 0 ];then 7 style=`ls -ld $file | head -c1` 8 case $style in 9 -) 10 echo "這是一個普通文件" 11 ;; 12 d) 13 echo "這是一個目錄文件" 14 ;; 15 l) 16 echo "這是一個鏈接文件" 17 ;; 18 *) 19 echo "這是其他類型文件" 20 ;; 21 esac 22 #若不存在,提示並退出 23 else 24 echo "該文件不存在" 25 exit 2 26 fi 27 28 #刪除變數 29 unset file style
二、迴圈語句
在我們的腳本中,肯定也少不了對某一段代碼重覆運行多次的操作,此時,我們就會用到迴圈語句。迴圈語句中,都是有進入條件和退出條件的,迴圈的次數也分為事先已知和事先未知(事先已知就是我們知道迴圈的具體次數,事先未知則是指當滿足某一條件就進行迴圈,但是次數是不確定的。)。接下來,我們就來看看關於迴圈語句的用法。
2.1 for迴圈
for迴圈的執行機制是:一次將列表中的元素賦值給“變數名”;每次賦值後即執行一次迴圈體;直到列表中的元素耗盡,迴圈結束。基本的語法有兩種:
1)for 變數名 in 列表 ; do
迴圈體
done
關於列表的生成方法,如下:
①直接給出列表
②整數列表:
(a){start…end}
(b)`seq start end`
③返回列表的命令
$(COMMAND)
④使用glob通配符如:
*.sh
⑤變數引用
$i,$*
2)for (( exp1; exp2; exp3 )); do
迴圈體
done
更清晰的可以從下圖中看出:
Example:
1)列印九九乘法表
1 #!/bin/bash 2 #判斷i的值是否在1-9 3 for i in {1..9};do 4 # 判斷j的值是否在1-$i 5 for j in `seq 1 $i`;do 6 # 若在,則列印i*j的值 7 echo -en "$i*$j = $[$i*$j]\t" 8 done 9 echo 10 done 11 12 #刪除變數 13 unset i j
2)輸入正整數n,計算1+…+n的和
1 #!/bin/bash 2 #定義變數 3 sum=0 4 read -p "請輸入一個正整數:" num 5 #判斷num是否是正整數 6 if [[ $num =~ ^[[:digit:]]+$ ]];then 7 # 若是,當i在1-$num時,輸出sum值 8 for i in `seq 1 $num`;do 9 let sum+=$i 10 done 11 echo "sum=$sum" 12 #若不是,提示輸出正整數 13 else 14 echo "請輸入一個正整數!" 15 fi 16 17 #刪除變數 18 unset i sum num
2.2 while迴圈
while迴圈比for迴圈略複雜一些,具體語法如下:
while CONDITION; do
迴圈體
done
註意:1、進入條件:CONDITION為true;退出條件:CONDITION為false。
2、CONDITION為迴圈控制條件:進入迴圈之前,先做一次判斷;每一次迴圈之後會再次做判斷;條件為“true”,則執行一次迴圈;知道條件測試狀態為“false”終止迴圈。
3、CONDITION一般應該有迴圈控制變數;此變數的值會在迴圈體不斷地被修正。
Example:
1)計算100以內所有正奇數之和
1 #!/bin/bash 2 #定義變數 3 i=1 4 sum=0 5 #當i<100時,執行下麵語句 6 while [ $i -le 100 ];do 7 #當i為奇數時,另sum=sum+I,i=i+1 8 while [ $[i%2] -eq 1 ];do 9 let sum+=$i 10 let i+=1 11 done 12 # 當i不為奇數時,i=i+1 13 let i+=1 14 done 15 #輸出結果 16 echo "sum=$sum" 17 18 #刪除變數 19 unset i sum
2.3 until迴圈
until迴圈的語法和while的語法類似,但是進入和退出的條件卻剛好相反,所以不常用,只要我們瞭解即可。具體語法如下:
until CONDITION; do
迴圈體
done
註意:1、進入條件:CONDITION為false;退出條件:CONDITION為true。
2、do和done成對出現。
Example:
1)迴圈輸出1-10
1 #!/bin/bash 2 #定義變數 3 i=1 4 #當i>10時,退出迴圈 5 until [ $i -gt 10 ];do 6 # 輸出i的值,i=i+1 7 echo $i 8 let i+=1 9 done 10 11 #刪除變數 12 unset i
2.4 select迴圈
select迴圈主要用於創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,並顯示PS3提示符,等待用戶輸入。
用戶輸入菜單列表中的某個數字,執行相應的命令。
用戶輸入被保存在內置變數REPLY中。
select的具體語法如下:
select variable in list; do
迴圈體命令
done
註意:①select是個無線迴圈,因此要記住用break命令退出迴圈,或用exit命令終止腳本。也可以按ctrl+c退出迴圈。
②select經常和case聯合使用。
③與for迴圈類似,可以省略in list,此時使用位置變數。
Example:
1)生成菜單,並顯示選中的價錢。
1 #!/bin/bash 2 #定義PS3提示符 3 PS3="Please choose the menu:" 4 #輸出菜單 5 select menu in yangroutang mifan hulatang jiaozi lamian huimian quit 6 do 7 # 判斷選擇 8 case $REPLY in 9 1|4) 10 echo "The price is 20" 11 ;; 12 2|5) 13 echo "The price is 12" 14 ;; 15 3|6) 16 echo "The price is 10" 17 ;; 18 7) 19 break 20 ;; 21 *) 22 echo "Choose error" 23 ;; 24 esac 25 done
2.5 迴圈小補充
2.5.1 迴圈控制語句 continue&break
迴圈控制語句用於迴圈體中,常見的控制語句有兩種,continue和break。接下來我們就來看看兩者的區別:
continue語句結束的是本輪迴圈,直接進入下一輪判斷;最內層是第1層。
break語句結束的則是整個迴圈,最內層為第1層。
Example:
1)求(1+3+…+49+53+…+99)的和
1 #定義變數 2 sum=0 3 for ((i=1;i<=100;i++));do 4 # 當i為奇數時,繼續執行 5 if [ $[i%2] -eq 1 ];then 6 # 當i=51時,跳過該迴圈 7 if [ $i -eq 51 ];then 8 continue 9 fi 10 let sum+=$i 11 fi 12 done 13 echo "sum=$sum" 14 15 #刪除變數 16 unset i sum
2)求(1+3+…+49)的和
1 #!/bin/bash 2 #定義變數 3 sum=0 4 for ((i=1;i<=100;i++));do 5 # 當i為奇數時,繼續執行 6 if [ $[i%2] -eq 1 ];then 7 # 當i=51時,跳出整個迴圈 8 if [ $i -eq 51 ];then 9 continue 10 fi 11 let sum+=$i 12 fi 13 done 14 echo "sum=$sum" 15 16 #刪除變數 17 unset i sum
2.5.2 迴圈控制命令shift
位置參數可以用shift命令左移,比如shift 3表示原來的$4現在變成$1,原來的$5現在變成$2等等,原來的$1,$2,$3丟棄,$0不移動。不帶參數的shift命令相當於shift 1。
我們知道,對於位置變數或命令行參數,其個數必須是確定的,或者當shell程式不知道其個數時可以把所有參數一起賦值給變數$*。當用戶要求shell在不知道位置變數個數的情況下,還能逐個的把參數一一進行處理,也就是在$1後為$2等。在shift命令執行前變數$1的值在shift命令執行後就不可用了。
Example: