回顧: 循環
循環控制:break,continuewhile , for循環的特殊用法for (());do 循環體donewhile read VARAIBLE;do 循環體done < /PATH/FROM/SOMEFILE
bash腳本編程:
case語句: 多分支語句: if CONDITION1;then 分支1 elif CONDITION2;then 分支2 ... else CONDITION;then 分支n fi
示例1:顯示一個菜單給用戶; cpu)display cpu information mem)display memory information disk)display disks information quit)quit
要求:(1)提示用戶給出選擇; (2)正確的選擇則給出相應的信息;否則,提示重新選擇正確的選項
#!/bin/bash##cat << EOF cpu) display cpu information mem) display memory infomration disk) display disks information quit) quit ===================== EOFread -p "Enter your option:" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do echo "cpu,mem,disk,quit" read -p "Enter your option again:" optiondoneif [ "$option" == "cpu" ];then lscpuelif [ "$option" == "mem" ];then free -melif [ "$option" == "disk" ];then df -helif [ "$option" == "quit" ];then exitfi
case語句的語法格式:只適用于一個變量反復跟多個字符串等值或者不等值比較時,來匹配。
case $VARAIBLE inPAT1) 分支1 ;; PAT2) 分支2 ;; *) 分支n ;; esac
示例1 使用上邊的腳本,把通過if的代碼,來用case語句實現
#!/bin/bash##cat << EOF cpu) display cpu information mem) display mem information disk) display disks information quit) exitEOFread -p "Enter your option :" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do echo "cpu,mem,disk,quit" read -p "Enter your option again :" optiondonecase $option incpu) lscpu ;; mem) free -m ;; disk) df -h ;; quit) exit;;esac
示例2:寫一個服務框架腳本;
$lockfile,值/home/soft/SCRIPT_NAME
(1)此腳本可接受start,stop,restart,status四個參數之一;
(2)如果參數非此四者,則提示使用幫后退出;
(3)start,則創建lockfile,并顯示啟動;stop,則刪除lockfile,并顯示停止;restart,則先刪除文件在創建此文件,而后顯示重啟完成;status,如果lockfile存在,則顯示running,否則,則顯示為stopped。
#!/bin/bash#prog=$(basename $0) lockfile=/home/soft/$progcase $1 instart) if [ -f $lockfile ];then echo "$prog is running" else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed" fi ;; stop) if [ -f $lockfile ];then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finshed" else echo "$prog is not running" fi ;; restart) if [ -f $lockfile ];then rm -f $lockfile touch $lockfile echo "$prog is restart" else touch -f $lockfile echo "start $prog finshed" fi ;; status) if [ -f $lockfile ];then echo "$prog is running" else echo "$prog is stopped" fi ;; *) echo "Usage: $prog {start|stop|restart|status}" exit 1esac
函數:function
過程是編程:代碼重用 模塊化編程 結構化編程 把一段獨立功能的代碼當做一個整體,并為之一個名字;命名的代碼段,此即為函數; 注意:定義函數的代碼段不會自動執行,再調用時執行;所謂調用函數,在代碼中給定函數名即可;函數名出現的任何位置,在代碼執行時,都會被自動替換為函數代碼;
語法一
function f_name { …函數體… }
語法二
f_name() { …函數體… }
函數的生命周期:每次被調用時創建,返回時終止;
其狀態返回結果為函數體重運行的最后一條命令的狀態結果; 自定義狀態返回值,需要使用:returnreturn[0-255]0是成功1-255失敗
示例1:給定一個用戶名,取得用戶Id號和默認shell;
正常不用函數來寫這段代碼的話是這樣的
#!/bin/bash#if id "$1" &> /dev/null ;then grep "^$1\>" /etc/passwd | cut -d: -f 3,7else echo "NO such user"fi
用函數來定義 注意:函數里邊不能直接用$1..來直接充當參數。
#!/bin/bash#if id "$1" &> /dev/null ;then grep "^$1\>" /etc/passwd | cut -d: -f 3,7else echo "NO such user"fi[root@centous1 lianxi]# bash +x user2.sh user1^C
這個時候直接運行時是沒有結果的,我們需要調用這個函數。
#!/bin/bash#userinfo() { if id "$username" &> /dev/null;then grep "^$username\>" /etc/passwd |cut -d: -f 3,7else echo "NO such user"fi} username=$1userinfo [root@centous1 lianxi]# bash +x user2.sh user14323:/bin/bash
同時,我們還可以多次調用
#!/bin/bash#userinfo() { if id "$username" &> /dev/null;then grep "^$username\>" /etc/passwd |cut -d: -f 3,7else echo "NO such user"fi} username=$1userinfo username=$2userinfo [root@centous1 lianxi]# bash +x user2.sh user1 user24323:/bin/bash4324:/bin/bash
示例2:把前邊的服務腳本用函數來編寫
#!/bin/bash#prog=$(basename $0) lockfile=/home/soft/$progstart (){ if [ -f $lockfile ];then echo "$prog is running" else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed" fi}stop (){ if [ -f $lockfile ];then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finshed" else echo "$prog is not running" fi}status () { if [ -f $lockfile ];then echo "$prog is running" else echo "$prog is stopped" fiusage () { echo "Useage: $lockfile { start|stop|restart|status}"}case $1 instart) start ;; stop) stop ;; restart) stop start ;; status) status ;; *) usageesac[root@centous1 lianxi]# bash +x testdir3.sh startstart testdir3.sh finshed [root@centous1 lianxi]# bash +x testdir3.sh stopstop testdir3.sh finshed [root@centous1 lianxi]# vim testdir3.sh[root@centous1 lianxi]# bash +x testdir3.sh stoptestdir3.sh is not running [root@centous1 lianxi]# bash +x testdir3.sh stUseage: /home/soft/testdir3.sh { start|stop|restart|status}
函數返回值:
函數執行結果返回值: (1)使用echo或printf命令進行輸出; (2)函數體重調用的命令的執行結果;
函數的退出狀態碼:
(1)默認取決于函數體重執行的最后一條命令的退出狀態碼; (2)自定義:return
函數可以接收參數:
傳遞參數給函數: 在函數體中,可以使用$1,$2...醫用傳遞給函數的參數;還可以在函數 中使用$* $@引用所有參數,$#引用傳遞的參數個數 在調用函數時,在函數名后面以空白符分隔給定參數列表即可,例如,arg1 arg2
再這里應該注意的是,一個腳本中需要使用$1,$2…時,注意,如果其中有函數,那么函數會直接調用,而不是經過腳本之后再調用。
示例;添加10個用戶, 添加用戶的功能使用函數實現,用戶名作為參數傳遞給函數;
#!/bin/bash##addusers(){ if id $1 &> /dev/null;then return 5 else useradd $1 retval=$? return $retval fi}for i in {1..10};do addusers ${1}${i} retval=$? if [ $retval -eq 0 ];then echo "Add user ${1}${i} finshed" elif [ $retval -eq 5 ];then echo "user ${1}${i} exists." else echo "Unkown Error" fidone[root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1 + id abc1 + useradd abc1 + retval=0+ return 0+ '[' 0 -eq 0 ']'+ echo 'Add user abc1 finshed'..... ..... [root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1 + id abc1 + return 5+ retval=5+ '[' 5 -eq 0 ']'+ '[' 5 -eq 5 ']'+ echo 'user abc1 exists.'.... ....
變量作用域:
局部變量:
作用域的函數的生命周期;在函數結束時被自動銷毀;
定義局部變量的方法:local VARIABLE=VALUE
本地變量:作用域是運行腳本的shell進程的生命周期;因此,其作用域是腳本程序文件。
用例子來說明
#!/bin/bash#name=tomsetname(){ name=jarry echo "$name"} setnameecho "$name"~ [root@centous1 lianxi]# bash -x 123.sh+ name=tom + setname + name=jarry + echo jarry jarry + echo jarry jarry#!/bin/bash#name=tomsetname(){ local name=jarry echo "$name"} setnameecho "$name"[root@centous1 lianxi]# bash -x 123.sh+ name=tom + setname + local name=jarry + echo jarry jarry + echo tom tom
原創文章,作者:forest,如若轉載,請注明出處:http://www.www58058.com/39023