Shell腳本編程3
一、雜項知識整理
1、select與case
select是個無限循環,因此要記住用break命令退出循環,或用exit命令終止腳本。也可以按ctrl+c退出循環,自動生成數字的選擇項,適合創建菜單。
select經常和case聯合使用。與for循環類似,可以省略in LIST,此時使用位置參量$1、$2等傳遞參數。
case不是無限循環,select適合于case一起使用,當使用的時候case在其內部使用的分支參數是選項代表的參數而不是選項數字。
#!/bin/bash # PS3="what do you want?" select caidan in gongbaojiding qingzhengyu wanzi;do case $caidan in gongbaojiding) echo "cost 10" break ;; wanzi) echo "cost 30" ;; *) echo "cost 25" ;; esac done echo $REPLY
2、set命令查看所有環境變量和系統定義的函數。
二、事例詳解及命令
1、while循環的特殊用法(遍歷文件的每一行):
while read line;do
循環體
done < /PATH/FROM/SOMEFILE
一次讀取文件中的米一行,且將行賦值給變量line
例如:掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填充用戶名和單位電話為62985665,并提示該用戶的GECOS信息修改成功。
#!/bin/bash #read line #test while read LINE; do if echo $LINE | grep "::" &> /dev/null; then USER=`echo $LINE | cut -d: -f1` chfn -f $USER $USER &> /dev/null chfn -p "62985600" $USER &> /dev/null echo "$USER infomation has changed" fi done < /etc/passwd
2、特殊用法之雙小括號方法,即(())格式,也可以用于算數運算。雙小括號方法也可以使bash shell實現c語言風格的變量操作。for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式));do
循環體
done
控制變量的初始化:僅在運行到循環代碼段時執行一次;
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷
#!/bin/bash #9*9 # for ((i=1;i<=9;++i));do for ((j=1;j<=i;j++));do echo -ne "$j*$i=$[$i*$j]\t" done echo done echo 3、select variable in list do 循環體命令 done
select循環主要用于創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,并顯示PS3提示符,等待用戶輸入
用戶輸入菜單列表中的某個數字,執行相應的命令。
用戶輸入被保存在內置變量REPLY中。
4、函數介紹:函數是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程。它與shell程序形式上是相似的,不同的是他不是一個單獨的進程,不能獨立運行,而是shell程序的一部分。
函數和shell程序比較相似,區別在于:
shell程序在子shell中運行,而shell函數在當前shell中運行,因此在當前shell中,函數可以對shell中變量進行修改。若在函數定義了一個變量,腳本中也定義了同名的變量,在當前shell中echo此變量值的時候顯示的是函數中的值,因為腳本不執行在當前shell中。
5、函數定義:function funcname{}或funcname(){}
函數的定義和使用:可在交互式環境下定義函數;可將函數放在腳本文件中作為它的一部分;可放在只含函數的單獨文件中。
調用:函數只有被調用才會執行;調用:給定函數名;函數名出現的地方,會被自動替換為函數代碼。
函數返回值:函數有兩種返回值:函數的執行結果返回值和函數的退出狀態碼;
函數的退出狀態碼:默認取決于函數中執行的最后一條命令的退出狀態碼;自定義退出狀態碼,格式為:
return 從函數中返回,用最后狀態命令決定返回值
return 0 無錯誤返回
return 1-255 有錯誤返回
6、在交互環境下定義了函數將一直保留到用戶從系統退出或執行了unset funcname的命令
腳本中定義及使用函數:函數在使用前必須定義,因此應將函數定義放在腳本開始部分,直至shell首次依次執行到它后才能使用。調用函數僅使用其函數名即可。
用函數文件:可以將經常使用的函數存入函數文件,然后將函數文件載入shell。
一旦函數文件載入shell,就可以在命令行或腳本中調用函數??梢允褂?/span>set命令查看所有定義的函數,其輸出列表包括已經載入shell的所有函數。若要改動函數,首先用unset命令從shell中刪除函數,改動完畢后,再重新載入此文件。
函數文件創建好后載入shell用. filename或source filename,文件名要帶正確路徑
7、傳遞參數給函數:調用函數時,在函數名后面以空白分隔給定參數列表即可;例如:testfunc arg1 arg2
在函數體中,可以使用$1$2…調用這些參數,還可以使用$@$*$#等特殊變量。
8、在函數中定義局部變量的方法:local NAME=VALUE:局部變量定義后,只能在函數體內部使用此變量。
9、函數遞歸:函數直接或間接調用自身;注意遞歸層數。
遞歸實例:階乘是基斯頓.卡曼于1808年發明的運算符號,一個正整數的階乘是所有小于及等于該數的正整數的積,并且有0的階乘為1.自然數n的階乘寫作n!。
階乘用遞歸方式定義:0!=1;n!=(n-1)!*n=n(n-1)(n-2)…1
#!/bin/bash #jiecheng # fact() { if [ $1 -eq 0 -o $1 -eq 1 ];then echo 1 else echo $[$1*$(fact $[$1-1])] fi } fact $1
三、課后練習
1、斐波那契數列又稱黃金分割數列,因數學家列昂納多·斐波那契以兔子繁
殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:0、1、1、
2、3、5、8、13、21、34、……,斐波納契數列以如下被以遞歸的方法定義
:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2)
寫一個函數,求n階斐波那契數列
#!/bin/bash #rabit # GOLD() { if [ "$1" -eq 0 ];then echo 0 elif [ "$1" -eq 1 ];then echo 1 else echo $[$(GOLD $[$1-1])+$(GOLD $[$1-2])] fi } read -p "Please input a number: " NUM GOLD $NUM
2、實現漢諾塔
#!/bin/bash #Hanoi # Hanoi() { if [ "$1" -eq 1 ];then echo "$2--$4" else Hanoi $[$1-1] $2 $4 $3 echo "$2--$4" Hanoi $[$1-1] $3 $2 $4 fi } read -p "Please input a number: " N Hanoi $N X Y Z
原創文章,作者:SilencePavilion,如若轉載,請注明出處:http://www.www58058.com/37597
shell腳本能代替我們是實現一些自動化的功能,同時函數也是腳本中最常使用的思想,它能實現代碼重用和提高工作效率,對腳本而言,沒有特殊的捷徑,只有多寫,多看,才能快速提高自己的腳本能力。