2021-05-12 14:32:11
shell指令碼入門詳解及其範例
條件為真的分支程式碼
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:
1)測試shift命令
1 #!/bin/bash 2 until [ $# -eq 0 ];do 3 echo "The first argument is:$1,The number of arguments is:$#" 4 shift 5 done
2.5.3 信號捕捉trap
trap是一個shell內建命令,它用來在指令碼中指定信號如何處理。比如,按Ctrl+C會使指令碼終止執行,實際上系統傳送了SIGINT信號給指令碼進程,SIGINT信號的預設處理方式就是退出程式。如果要在Ctrl+C不退出程式,那麼就得使用trap命令來指定一下SIGINT的處理方式了。trap命令不僅僅處理Linux信號,還能對指令碼退出(EXIT)、偵錯(DEBUG)、錯誤(ERR)、返回(RETURN)等情況指定處理方式。
基本格式語法如下:
- trap ‘觸發指令’ 信號
自定義進程收到系統發出的指定信號後,將執行觸發指令,而不是執行原操作
- trap ‘’ 信號
忽略信號的操作
- trap ‘-’ 信號
恢復原信號的操作
- trap -p
列出自定義信號的操作,即提示當前使用的trap操作是什麼。
注意:①信號的表示方法:可以是完整信號/簡寫/數位(具體內容通過kill -l查詢)
②信號9,強制殺死,捕獲不到。
Example:
1)列印0-9,ctrl+c終止無效
1 #!/bin/bash 2 #設定信號捕獲 3 trap 'echo press ctrl+c' 2 4 for ((i=0;i<10;i++));do 5 sleep 1 6 echo $i 7 done
2)列印0-9,3之前ctrl+c不能終止,3之後恢復,能終止
1 #!/bin/bash 2 #設定信號捕獲 3 trap '' 2 4 trap -p 5 for ((i=0;i<3;i++));do 6 sleep 1 7 echo $i 8 done 9 trap '-' SIGINT 10 for ((i=3;i<10;i++));do 11 sleep 1 12 echo $i 13 done
2.5.4 建立無限迴圈
在我們的shell指令碼中,可以建立一個死迴圈,具體設定如下:
while true;do
迴圈體
done
2.5.5 在迴圈語句中執行並行命令
當我們需要在指令碼裡執行一條命令很多次的時候,我們可以將其設定為並行執行,這樣可以極大的提升指令碼執行速度,但是也有缺點,並行執行的話,相當於開了很多子shell一起執行,執行速度上來了,但是對資源的消耗也增多了。
具體的用法範例如下:
for name in 列表; do
{
迴圈體
}$
done
wait
Example:
1)搜尋自己指定的的IP(子網掩碼為24的)的網段中,up的ip地址
1 #!/bin/bash 2 #定義變數 3 read -p "Please input network (eg:172.17.0.1): " net echo $net |egrep -o "<(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])>" 4 #判斷網段是否符合規範 5 [ $? -eq 0 ] || ( echo "input error";exit 10 ) 6 #判斷網段內哪些IP能ping通,並行執行 7 IP=`echo $net |egrep -o "^([0-9]{1,3}.){3}"` 8 for i in {1..254};do 9 { 10 ping -c 1 -w 1 $IP$i &> /dev/null && 11 echo "$IP$i is up" 12 }& 13 done 14 wait 15 16 #刪除變數 17 unset net IP i
三、小補充
介紹了這麼多語法,我們來玩一些好玩的吧~下面是小編給大家分享的幾個有意思的指令碼
1)列印等腰三角形(帶閃爍)
1 #!/bin/bash 2 #num=總行號 i=第幾行 j=*個數 k=空格個數 3 read -p "請輸入一個數位:" num 4 for i in `seq 1 $num`;do 5 for k in `seq 1 $[$num-$i]`; do 6 echo -n " " 7 done 8 for j in `seq 1 $[2*$i-1]`;do 9 if [ $j -eq 1 ] || [ $j -eq $[2*$i-1] ] || [ $i -eq $num ];then 10 color=$[RANDOM%5+31] 11 echo -en " 33[1;$color;5m* 33[0m" 12 else 13 echo -n "*" 14 fi 15 done 16 echo 17 done 18 19 #刪除變數 20 unset num i j k color
2)列印國際象棋棋盤
1 #!/bin/bash 2 #定義變數 3 color_1=" 33[1;44m 33[0m" 4 color_2=" 33[1;45m 33[0m" 5 for (( i=1;$i <=8;i++ ));do 6 for (( j=1;$j <=8;j++ ));do 7 if [ $[$i%2] == 1 ] && [ $[$j%2] == 1 ];then 8 echo -en "$color_1$color_2" 9 elif [ $[$i%2] == 0 ] && [ $[$j%2] == 0 ];then 10 echo -en "$color_2$color_1" 11 fi 12 done 13 echo 14 done 15 16 #刪除變數 17 unset color_1 color_2 i j
具體的顏色大家可以根據自己的喜好來調整~
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-09/146913.htm
相關文章