shell指令碼進階 詳解及其例項
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/bash2until [ $# -eq 0 ];do3 echo "The first argument is:$1,The number of arguments is:$#"4 shift5 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/bash2 #設定訊號捕獲3 trap 'echo press ctrl+c' 24 for ((i=0;i<10;i++));do5 sleep 16 echo $i7 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 '-' SIGINT10 for ((i=3;i<10;i++));do11 sleep 112 echo $i13 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 done14 wait15 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 ];then10 color=$[RANDOM%5+31]11 echo -en "\033[1;$color;5m*\033[0m"12 else13 echo -n "*"14 fi 15 done16 echo17 done18 19 #刪除變數20 unset num i j k color
具體的效果大家可以自己去嘗試,就是下面兩張圖配合出來的效果:
2)列印國際象棋棋盤
1 #!/bin/bash 2 #定義變數 3 color_1="\033[1;44m \033[0m" 4 color_2="\033[1;45m \033[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 ];then10 echo -en "$color_2$color_1"11 fi 12 done13 echo14 done15 16 #刪除變數17 unset color_1 color_2 i j