case語句shell
何時用到case?bash
當屢次判斷變量是否屬於某個字符串時候框架
case語句的語法格式:ide
case $VARAIBLE in 函數
PAT1) 注:若是PAT1匹配到$VARAIBLE時候,執行分支1 同理測試
分支1ui
;; 注:每個判斷條件都要雙分號,同理spa
PAT2) rest
分支2orm
;;
...
*) 都不屬於以上狀況,執行分支n
分支n
;;
esac 最後一個不須要
特性:case支持glob風格的通配符:
*:任意長度的任意字符;
?:任意單個字符;
[]:範圍內任意單個字符;
a|b:a或b;
case簡單示例:寫一個服務框架腳本;
(1) 此腳本可接受start, stop, restart, status四個參數之一;
(2) 若是參數非此四者,則提示使用幫助後退出;
(3) start,則建立lockfile,並顯示啓動;stop,則刪除lockfile,並顯示中止;restart,則先刪 除此文件再建立此文件,然後顯示重啓完成;status,若是lockfile存在,則顯示running,不然,則顯示爲stopped.
#!/bin/bash # # chkconfig: - 50 50 注:定義運行級別、啓動優先級、關閉優先級 # description: test service script 注:描述信息 # prog=$(basename $0) 注:以變量替換的方式取路徑基名,並賦值給變量prog lockfile=/var/lock/subsys/$prog 注:給變量lockfile賦值一個文件路徑 case $1 in start) if [ -f $lockfile ]; then 注:-f進行文件存在性測試 echo "$prog is running yet." else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed." 注:以命令狀態返回值判斷 fi 文件是否建立成功 ;; stop) if [ -f $lockfile ]; then 邏輯同理 rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finished." else echo "$prog is not running." fi ;; restart) if [ -f $lockfile ]; then rm -f $lockfile touch $lockfile echo "restart $prog finished." else touch -f $lockfile echo "start $prog finished." fi ;; status) if [ -f $lockfile ]; then echo "$prog is running" else echo "$prog is stopped." fi ;; *) echo "Usage: $prog {start|stop|restart|status}" exit 1 esac
函數:function
爲何要用到函數?
爲了簡化本身寫的代碼量,重複屢次使用的功能能夠包裝成函數屢次調用。也會使你的代碼更有結構
什麼是函數?
把一段獨立功能的代碼看成一個總體,併爲之一個名字;命名的代碼段,此即爲函數;
怎樣使用函數?
定義函數的代碼段不會自動執行,在調用時執行;所謂調用函數,在代碼中給定函數名便可;
函數名出現的任何位置,在代碼執行時,都會被自動替換爲函數代碼;函數的生命週期:每次被調用時建立,返回時終止;
語法一:
function f_name {
...函數體...
}
語法二:
f_name() {
...函數體...
}
自定義狀態返回值方法:
其狀態返回結果爲函數體中運行的最後一條命令的狀態結果;
自定義狀態返回值,須要使用:return
return [0-255]
0: 成功
1-255: 失敗
函數的執行結果返回值:
(1) 使用echo或printf命令進行輸出;
(2) 函數體中調用的命令的執行結果;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函數使用舉例1:給定一個用戶名,取得用戶的id號和默認shell;
#!/bin/bash # userinfo() { if id "$username" &> /dev/null; then grep "^$username\>" /etc/passwd | cut -d: -f3,7 else echo "No such user." fi } username=$1 userinfo username=$2 userinfo
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函數使用舉例2:服務腳本框架
#!/bin/bash # # chkconfig: - 50 50 # description: test service script prog=$(basename $0) lockfile=/var/lock/subsys/$prog start() { 注:函數定義 if [ -f $lockfile ]; then echo "$prog is running yet." else touch $lockfile [ $? -eq 0 ] && echo "start $prog finshed." fi } stop() { if [ -f $lockfile ]; then rm -f $lockfile [ $? -eq 0 ] && echo "stop $prog finished." else echo "$prog is not running." fi } status() { if [ -f $lockfile ]; then echo "$prog is running" else echo "$prog is stopped." fi } usage() { echo "Usage: $prog {start|stop|restart|status}" } case $1 in start) start ;; 注:調用start函數,如下同理 stop) stop ;; restart) stop start ;; status) status ;; *) usage exit 1 ;; esac
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
函數能夠接受參數:
1.在函數體中當中,可使用$1,$2, ...引用傳遞給函數的參數;
2.還能夠函數中使用$*或$@引用全部參數,
3. $#引用傳遞的參數的個數;
例如,testfunc arg1 arg2 arg3 ...
注:在調用函數時,在函數名後面以空白符分隔給定參數列表便可
示例:添加10個用戶,
添加用戶的功能使用函數實現,用戶名作爲參數傳遞給函數;
函數能夠接受參數舉例1
#!/bin/bash # # 5: user exists 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} finished." elif [ $retval -eq 5 ]; then echo "user ${1}${i} exists." else echo "Unkown Error." fi done
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
練習:寫一個腳本;
使用函數實現ping一個主機來測試主機的在線狀態;主機地址經過參數傳遞給函數;
主程序:測試172.16.1.1-172.16.67.1範圍內各主機的在線狀態;
練習:寫一個腳本;
打印NN乘法表;
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
變量做用域
局部變量:做用域是函數的生命週期;在函數結束時被自動銷燬;
定義局部變量的方法:local VARIABLE=VALUE
本地變量:做用域是運行腳本的shell進程的生命週期;所以,其做用範圍爲當前shell腳本程序文件;
變量做用域舉例1
#!/bin/bash # name=tom setname() { local name=jerry echo "Function: $name" } setname echo "Shell: $name"
函數遞歸
函數直接或間接調用自身;
10!=10*9!=10*9*8!=10*9*8*7!=...
n*(n-1)!=n*(n-1)*(n-2)!=
函數遞歸舉例1
#!/bin/bash # fact() { if [ $1 -eq 0 -o $1 -eq 1 ]; then echo 1 else echo $[$1*$(fact $[$1-1])] fi } fact $1
函數遞歸舉例2
1,1,2,3,5,8,13,21,...
#!/bin/bash # fab() { if [ $1 -eq 1 ]; then echo -n "1 " elif [ $1 -eq 2 ]; then echo -n "1 " else echo -n "$[$(fab $[$1-1])+$(fab $[$1-2])] " fi } for i in $(seq 1 $1); do fab $i done echo
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
編外擴展
示例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 infomation disk) display disks information quit) quit =============================== EOF read -p "Enter your option: " option while [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]; do echo "cpu, mem, disk, quit" read -p "Enter your option again: " option done if [ "$option" == "cpu" ]; then lscpu elif [ "$option" == "mem" ]; then free -m elif [ "$option" == "disk" ]; then fdisk -l /dev/[hs]d[a-z] else echo "quit" exit 0 fi