標籤:bash函數
bash支援使用函數,函數出現的地方,而自動被替換成函數定義的代碼,一個函數定義後可以多次被重複使用,大大減少代碼量
函數定義格式:
第一種
FuncName() { 函數體 }
第二種
function FuncName { 函數體}
函數有兩種傳回值:
正常返回的資料:
函數中的列印語句,如echo或print
函數中命令的執行結果
執行狀態傳回值:
取決於函數中執行的最後一條語句,最後一條執行成功返回0,否剛返回其它
反回值可以自訂:使用return N # N為自訂傳回值
函數可以接受參數:
在函數體可以使用類似指令碼調用位置參數一樣的參數
$1, $2, ...
$#
$*, [email protected]
如果想把指令碼的全部位置參數,統統傳遞給指令碼中某函數使用,怎麼辦?
使用$*傳遞,如果想一個一個使用,則判斷$#有幾個,再迴圈一個一個的使用
如果在函數中使用變數:變數範圍
在函數中使用了在主程式中聲明的變數,重新賦值會直接修改主程式中的變數;
如果不期望函數與主程式中的變數衝突,函數中使用變數都用local修飾;即使用局部變數;
在函數中使用了在主程式中沒有聲明的變數,在函數執行結束後即被撤消,無論是否使用local修飾符;
應用樣本:
寫一個指令碼,完成如下功能
1、顯示如下菜單
disk) show disk info
mem) show memory info
cpu) show cpuinfo
2、顯示使用者選定的內容;
#!/bin/bash#showMenu() { ## 第一種定義函數名的方法cat << EOFdisk) show disk infomem) show memory infocpu) show cpuinfoquit) exit scriptEOF}function main { ## 第二種調用函數的方法while true ;doshowMenu ## 調用定義的函數,函數內嵌函數。read -p "please enter menu option: " optionoption=`echo $option | tr ‘A-Z‘ ‘a-z‘` case $option in disk) df -h ;; mem) free -m ;; cpu) cat /proc/cpuinfo ;; quit) exit 0 ;; *) echo "error option." esacdone}main ## 調用函數
寫一個指令碼,判定172.16.0.0網路內有哪些主機線上,線上的用綠色顯示,不線上的用紅色顯示;要求,編程中使用函數;
#!/bin/bash#cnetping() { for i in {1..254};do ping -c 1 -w 1 $1.$i done}# cnetping 192.168.1.= 192.168.1+$1bnetping() { for j in {0..255};do cnetping $1.$j done}# bnetping 172.16. = 172.16+$j+$ianetping() { for k in {0..255};do bnetping $1.$k done}# anetping 10.=10.$k+$j+$iread -p "enter IPaddr: " IPaddrNetType=`echo $IPaddr | cut -d‘.‘ -f1`if [ $NetType -ge 0 -a $NetType -le 127 ];then anetping `echo $IPaddr | awk -F‘.‘ ‘{print $1}‘`elif [ $NetType -ge 128 -a $NetType -le 191 ];then bnetping `echo $IPaddr | awk -F‘.‘ ‘{print $1"."$2}‘`elif [ $NetType -ge 192 -a $NetType -le 223 ];then cnetping `echo $IPaddr | awk -F‘.‘ ‘{print $1"."$2"."$3}‘`else echo "error IP"fi
寫一個指令碼,完成如下功能(使用函數):
1、提示使用者輸入一個可執行命令;
2、擷取這個命令所依賴的所有庫檔案(使用ldd命令);
3、複製命令至/mnt/sysroot/對應的目錄中
解釋:假設,如果複製的是cat命令,其可執行程式的路徑是/bin/cat,那麼就要將/bin/cat複製到/mnt/sysroot/bin/目錄中,如果複製的是useradd命令,而useradd的可執行檔路徑為/usr/sbin/useradd,那麼就要將其複製到/mnt/sysroot/usr/sbin/目錄中;
4、複製各庫檔案至/mnt/sysroot/對應的目錄中,其要求命令;
#!/bin/bash#copytarget=/mnt/sysroot[ -d $copytarget ] || mkdir -p $copytargetcommand () {if which $COMMAND &> /dev/null;then COMMAND=`which --skip-alias $COMMAND`else return 5fi}copycommand() { command_dir=${copytarget}`dirname $COMMAND` [ -d ${command_dir} ] || mkdir -p ${command_dir} [ -f ${copytarget}${COMMAND} ] || cp $COMMAND ${command_dir}}copylib() { for i in `ldd $COMMAND | grep -o "/[^[:space:]]\{1,\}"`;do libdir=${copytarget}`dirname $i` [ -d $libdir ] || mkdir $libdir [ -f ${copytarget}${i} ] || cp $i $libdir done}while true;doread -p "please enter command: " COMMAND[ "$COMMAND" == ‘quit‘ ] && exit 7 command[ $? -eq 5 ] && continue copycommand copylibdone
寫一個指令碼,完成如下功能(使用函數):
1、指令碼使用格式:
mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefile
2、如果檔案事先不存在,則建立;且前幾行內容如下所示:
#!/bin/bash
# Description: script description
# Author: script author
#
3、如果事先存在,但不空,且第一行不是“#!/bin/bash”,則提示錯誤並退出;如果第一行是“#!/bin/bash”,則使用vim開啟指令碼;把游標直接定位至最後一行
4、開啟指令碼後關閉時判斷指令碼是否有語法錯誤
如果有,提示輸入y繼續編輯,輸入n放棄並退出;
如果沒有,則給此檔案以執行許可權;
#!/bin/bash##mkscript.sh [-D|--description "script description"] [-A|--author "script author"] /path/to/somefilewhile true;do[ $# -lt 1 ] && breakcase $1 in -D|--description) description=$2 shift 2 ;; -A|--author) author=$2 shift 2 ;; *) file=$1 shift 1esacdone[ -d `dirname $file` ] || mkdir `dirname $file`if ! [ -e $file ];then echo -e "#!/bin/bash\n# Description:${description}\n# Author:${author}\n#" > $fileelif [ -f $file ];then head -1 $file | grep ‘#!/bin/bash‘ &> /dev/null && vim +$ $fileelse echo " error $file not scripts file."; exit 7fi## 檢查指令碼while true;doif bash -n $file &> /dev/null;then chmod +x $file breakfiread -p "enter Y contiue ,N exit script!" option case $option in y|Y) vim $file ;; n|N) exit 8 ;; *) echo "error option" esacdone
本文出自 “菜鳥日誌” 部落格,請務必保留此出處http://zkxfoo.blog.51cto.com/1605971/1757295
bash 函數使用,實現模組化編程