shell編程之循環

       當需要重復運行特定的指令以滿足系統管理工作需要時,條件判斷語句if、case并不能很好地提供支撐,shell提供了for、while、until循環語句來滿足此需求。

一、for循環語句

       for循環用于重復整個對象列表,依次遍歷對列表中的獨立對象,直到遍歷列表完成,循環次數取決于列表中的對象數,每次循環都會執行指定的某個或某幾個命令。

需要特別指出的是,循環應該指定退出條件,否則循環將不會退出,一直執行。     

       1、for循環的語法格式:

       (1)、格式1

       for var in list;do

              Command1…

       done

       也可以這樣寫

       for var in list

do

       Command1…

done

 

       (2)、格式2

       格式二類似于C語言中的for循環

       for  ((變量初始值;循環退出條件;變量運算))

       do

              Command1…

       done

2、列表生成方式:

       (1)、直接給出列表,如for num in 1 2 3 4 5…;do….done

       (2)、使用文件通配名機制生成文件列表,如 for file in /var/*.sh

       (3)、使用{}或seq命令

                     for i in {1..10};do echo $i ;done;

                     for i in `seq 1 10`; do echo $i ;done;

              seq用法說明:

                     seq [start] [step] end

                          起始數字 步長 結束數字

例: seq 1 3 10

blob.png

       (4)、使用命令生成,如for file in `ls –A /etc/`;do echo $file;done;

       (5)、腳本參數引用$*、$@,注意兩者之間的區別,$*將所有參數當作一個字符串,$@將每個參數當作獨立的字符串。

 

例1:用for循環計算100以內正整數的奇數和&偶數和

#!/bin/bash
#
sum=0
for i in `seq 1 2 100`;do
sum=$[$sum+$i]
done
echo $sum

blob.png

第2種方式:

#!/bin/bash
#
sum=0
for ((num=1;num<=100;num+=2))
do
sum=$[$sum+$num]
done
echo $sum

blob.png

偶數的求和方式與奇數的相差無幾,這里不再重復。

 

例2、判斷/var/目錄下的文件類型

#!/bin/bash
#
dir=/var/
varfile=`ls -A $dir`
for file in $varfile;do
echo "The type of $dir$file is :`file -b $dir$file` "
done

blob.png

       for語句可與條件判斷結合,完成復雜任務。

例3、給腳本傳遞兩個正整數,第二個整數大于第一個整數,計算兩個整數之間所有整數的和。

#!/bin/bash
#
sum=0
if [ $# -lt 2 ];then
echo "Two int number needed"
exit 222
elif [ $1 -gt 0 ] &> /dev/null && [ $2 -gt 0 ]  &>/dev/null && [ $2 -gt $1 ] &> /dev/null;then
for  ((i=$1;i<=$2;i++));do
sum=$[$sum+$i]
done
echo $sum
else
echo "Please enter two int number,and the second arg must bigger than the first arg"
exit 22
fi

blob.png

 

二、while語句

       while語句在循環前對運行條件進行判斷,測試條件滿足時,循環將一直被執行,直到測試條件失敗,退出循環。

       1、while語法格式      

while Condition; do

循環體

done

Condition:循環控制條件;進入循環之前,先做一次判斷;每一次循環之后會再次做判斷;條件為“true”,則執行一次循環;直到條件測試狀態為“false”終止循環

因此:Condition一般應該有循環控制變量;而此變量的值會在循環體不斷地被修正

 

例1、計算100以內所有正整數之和

#!/bin/bash
#
num=1
sum=0
while [ $num -le 100 ];do
sum=$[$num+$sum]
num=$[$num+1]
done
echo $sum

blob.png

例2、利用變量RANDOM 生成10 個隨機數字,輸出這個10 數字,并顯示其中的最大者和最小者

#!/bin/bash
#
num=1
sum=0
min=65535
while [ $num -le 10 ];do
mingbo=`echo $RANDOM`
echo $mingbo
if [ $mingbo -gt $sum ];then
sum=$mingbo
else
sum=$sum
fi
if [ $mingbo -lt $min ];then
min=$mingbo
else
min=$min
fi
let num=$num+1
done
echo  "The max number is $sum"
echo  "The min number is $min"

blob.png

例3、打印國際象棋棋盤。

blob.png

國際象棋棋盤長8列、寬8行,共計64個格子,格子間色顯示。

通過觀察發現:行數+列數之和對2取模為0的顯示為黑色;行數+列數之和對2取模為1的顯示為白色。

腳本如下:

#!/bin/bash
#
declare -i num=1
while [ $num -le 8 ];
do
for  ((j=1;j<=8;j++))
do
[ $[$[$num+$j]%2] -eq 0 ] && echo -ne "\033[40m  \033[0m" || echo -ne "\033[41m  \033[0m"
done
((num++))
echo

done

blob.png

 

      

2、while的特殊用法:用于遍歷文件中的每一行

       while read line;

do

循環體

done < /Path/From/Some_file

例4、找出/etc/passwd文件中uid號為偶數,uid=gid的用戶

#!/bin/bash
#

while read line;do
userid=`echo $line | cut -d : -f3`
gid=`echo $line | cut -d : -f4`
if [[ $userid%2 -eq 0 && $gid%2 -eq 0 && $userid -eq $gid ]];then
uname=`echo $line | cut -d : -f1`
echo -e "The user whose id number is even is \033[32m$uname\033[0m,
        \n and his userid is \033[32m$userid\033[0m,
        \n his group id is \033[32m$gid\033[0m"
fi
done < /etc/passwd

blob.png

 

 

三、until語句

語法格式:

until Condition; do

循環體

done

       其用法與while語句基本類似。區別在于進入條件和退出條件不同。進入循環之前,先做一次判斷;每一次循環之后會再次做判斷;條件為“false”,則執行一次循環;直到條件測試狀態為“true”終止循環。

如:計算100以內的正整數之和,用until實現。

#!/bin/bash
#
num=1
sum=0
until [ $num -gt 100 ];do
sum=$[$sum+$num]
((num++))
done

echo $sum

blob.png

四、循環控制語句

       continue、break、shift

4.1 continue:用于退出當次循環,continue后面的循環體不再運行,而是直接進入下一次循環。

語法格式:

while CONDTIITON1; do

CMD1

if CONDITION2; then

continue

fi

CMDn

done

4.2 break:用于退出循環體,不再執行循環。

       while CONDTIITON1; do

CMD1

if CONDITION2; then

break

fi

CMDn

done

例1:要求用戶輸入一個用戶名,如輸入quit則退出腳本,若輸入的用戶名不存在則要求用戶重新輸入,輸入正確之后,顯示該用戶的uid。

#!/bin/bash
#
while true;do
read -p "Enter a user name : " uname
if [[ $uname == "quit" ]];then
break
elif [[ -z $uname ]] || ! id $uname &>/dev/null;then
echo "Wrong username,try again..."
continue
else
uid=`id -u $uname`
echo "$uname's userid is $uid"
fi

done

blob.png

4.3 shift:用于將腳本的位置參數左移一位或指定的位數。也就是執行shift之后,$2將變成$1.

 

例:給腳本傳遞3個參數,腳本使用格式:

script_name.sh [-D|–description "script description"] [-A|–author "script author"] /path/to/somefile;其中-D和-A可選。使用shift,分別保存傳遞的description、author、filename參數,并輸出。

#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Wrong option..."
echo "Usage : `basename $0` [-D|--description "script description"] [-A|--author "script author"] -f /path/to/somefile"
exit
fi

while [ $# -ge 2 ];do
case $1 in
-D|--description)
desc=$2
shift 2
;;
-A|--author)
author=$2
shift 2
;;
-f)
filename=$2
shift 2
;;
*)
echo "Wrong option..."
echo "Usage : `basename $0` [-D|--description "script description"] [-A|--author "script author"] -f /path/to/somefile"
exit
;;
esac
done
echo "filename is $filename;author is $author;file description is $desc"

blob.png

五、實戰演練 

1、用until循環實現國際象棋棋盤

#!/bin/bash
#
declare -i x=1

until [ $x -gt 8 ]
do
for  ((y=1;y<=8;y++))
do
[ $[$[$x+$y]%2] -eq 0 ] && echo -ne "\033[40m  \033[0m" || echo -ne "\033[41m  \033[0m"
[[ $y -eq 8 ]] && echo 
done
((x++))
done

blob.png

2、用*號輸出正三角,如:

blob.png

分析:第1行的空白數為:總行數-當前行數;假設總行數為5,則第1行的空白數為5-1=4

    第1行的*號數為:2*當前行數-1;第1行的*數為:2*1-1=1

    

   第2行的空白數為:總行數-當前行數;假設總行數為5,則第2行的空白數為5-2=3

    第2行的*號數為:2*當前行數-1;第1行的*數為:2*2-1=3

    

   第n行的空白數為:總行數-當前行數;假設總行數為m,則第n行的空白數為m-n

    第n行的*號數為:2*n-1;第n行的*數為:2*n-1

#!/bin/bash
#
lines=5

for i in `seq $lines`
do
for j in `seq $[$lines-$i]`
do
echo -n " "
done
for x in `seq $[$[$i*2]-1]`
do
echo -n "*"
done
echo
done

blob.png


 

 

 

原創文章,作者:M20-1鐘明波,如若轉載,請注明出處:http://www.www58058.com/37118

(0)
M20-1鐘明波M20-1鐘明波
上一篇 2016-08-18
下一篇 2016-08-18

相關推薦

  • 新鮮出爐的一篇好PPT,MySQL Optimizer團隊力作

    新鮮出爐的一篇好PPT,MySQL Optimizer團隊Senior Principal Software Engineer ?ystein同學親自操刀完成的《How to Analyze and Tune MySQL Queries for Better Performance》內容值得期待,有實現分析,有實戰用例。有需要的朋友可以點擊下載! 下載地址:…

    Linux干貨 2015-02-27
  • 備份練習

    課外整理 cp 功能: 復制文件或目錄說明: cp指令用于復制文件或目錄,如同時指定兩個以上的文件或目錄,且最后的目的地是一個已經存在的目錄,則它會把前面指定的所有文件或目錄復制到此目錄中。若同時指定多個文件或目錄,而最后的目的地并非一個已存在的目錄,則會出現錯誤信息參數:     -a 或 –archiv…

    Linux干貨 2016-08-08
  • HTTP響應連接介紹

    HTTP即超文本傳輸協議,web站點的實現就是基于HTTP協議得以實現。本文將詳細討論HTTP。 1. HTTP協議版本: HTTP從誕生到現在一共有如下幾個版本: HTTP 0.9:是最早的版本,為HTTP的原型版本,其功能非常簡陋; HTTP 1.0:此版本增加了很多新特性,如cache,method,MIME等,MIME的出現讓網頁不再是單純的純文本界…

    2017-05-31
  • SSH端口轉發

    ? SSH 會自動加密和解密所有SSH 客戶端與服務端之間的網絡數據。但是,SSH 還能夠將其他TCP 端口的網絡數據通過SSH 鏈接來轉發,并且自動提供了相應的加密及解密服務。這一過程也被叫做“隧道”(tunneling),這是因為SSH 為其他TCP 鏈接提供了一個安全的通道來進行傳輸而得名。例如,Telnet,SMTP,LDAP 這些TCP 應用均能夠…

    2017-09-10
  • shell變量的淺談

    變量本質上是存儲數據的一個或多個計算機內存地址,變量的命令規則包括: 1) 不能使用程序中的保留字,如if, for 2) 變量由字母、下劃線和數字組成,且不能以數字開頭 3) 要求風名知義 4) 統一命名規則:駝峰命名法 變量主要分為本地變量、環境變量、局部變量、位置變量和特殊變量 (1)本地變量:只對當前shell…

    2017-08-05
  • 20160802學習筆記

    useradd相關補充:      1.新建一個用戶創建時的一些默認權限在/etc/default/useradd配置中      2.新建用戶家目錄的過程實際就是將/etc/skel中的所有文件,拷貝到新建用戶的/home下,并更改為改用戶的用戶名   &n…

    Linux干貨 2016-08-03
欧美性久久久久