case語句、函數、return


條件判斷:case語句

case 變量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...

*)

默認分支

;;

esac


示例:


#!/bin/bash
#
cat << EOF
cpu) show cpu information;
mem) show memory information;
disk) show disk information;
quit) quit
============================
EOF
read -p "Enter a option: " option
while [ "$option" != 'cpu' -a "$option" != 'mem' -a "$option" != 'disk' -a "$option" != 'quit' ]; do
    read -p "Wrong option, Enter again: " option
done
case "$option" in
cpu)
lscpu 
;;
mem)
cat /proc/meminfo
;;
disk)
fdisk -l
;;
*)
echo "Quit..."
exit 0
;;
esac


練習:寫一個腳本,完成如下要求

(1) 腳本可接受參數:start, stop, restart, status; 

(2) 如果參數非此四者之一,提示使用格式後報錯退出;

(3) 如果是start:則創建/var/lock/subsys/SCRIPT_NAME, 並顯示“啓動成功”;

考慮:如果事先已經啓動過一次,該如何處理?

(4) 如果是stop:則刪除/var/lock/subsys/SCRIPT_NAME, 並顯示“停止完成”;

考慮:如果事先已然停止過了,該如何處理?

(5) 如果是restart,則先stop, 再start;

考慮:如果本來沒有start,如何處理?

(6) 如果是status, 則

如果/var/lock/subsys/SCRIPT_NAME文件存在,則顯示“SCRIPT_NAME is running...”;

如果/var/lock/subsys/SCRIPT_NAME文件不存在,則顯示“SCRIPT_NAME is stopped...”;


其中:SCRIPT_NAME爲當前腳本名;


總結:until, while, for, case


bash腳本編程:

while, for, case, until


bash腳本編程:


case語句:

case 變量引用 in

PAT1)

分支1

;;

PAT2)

分支2

;;

...

*)

分支n

;;

esac


case支持glob風格的通配符:

*: 任意長度任意字符;

?: 任意單個字符;

[]:指定範圍內的任意單個字符;

a|b: a或b


function:函數

過程式編程:代碼重用

模塊化編程

結構化編程


語法一:

function f_name {

...函數體...


語法二:

f_name() {

...函數體...

}


調用:函數只有被調用纔會執行;

調用:給定函數名

函數名出現的地方,會被自動替換爲函數代碼;


函數的生命週期:被調用時創建,返回時終止;

return命令返回自定義狀態結果;

0:成功

1-255:失敗


#!/bin/bash
#
function adduser {
   if id $username &> /dev/null; then
        echo "$username exists."
        return 1
   else
        useradd $username
        [ $? -eq 0 ] && echo "Add $username finished." && return 0
   fi
}
for i in {1..10}; do
    username=myuser$i
    adduser
done


示例:服務腳本

#!/bin/bash
#
# chkconfig: - 88 12
# description: test service script
#
prog=$(basename $0)
lockfile=/var/lock/subsys/$prog
start() {
    if [ -e $lockfile ]; then
echo "$prog is aleady running."
return 0
    else
touch $lockfile
[ $? -eq 0 ] && echo "Starting $prog finished."
    fi
}
stop() {
    if [ -e $lockfile ]; then
rm -f $lockfile && echo "Stop $prog ok."
    else
echo "$prog is stopped yet."
    fi
}
status() {
    if [ -e $lockfile ]; then
echo "$prog is running."
    else
echo "$prog is stopped."
    fi
}
usage() {
    echo "Usage: $prog {start|stop|restart|status}"
}
if [ $# -lt 1 ]; then
    usage
    exit 1
fi    
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
usage
esac


練習:打印九九乘法表,利用函數實現;


函數返回值:

函數的執行結果返回值:

(1) 使用echo或print命令進行輸出;

(2) 函數體中調用命令的執行結果;

函數的退出狀態碼:

(1) 默認取決於函數體中執行的最後一條命令的退出狀態碼;

(2) 自定義退出狀態碼:

return


函數可以接受參數:

傳遞參數給函數:調用函數時,在函數名後面以空白分隔給定參數列表即可;例如“testfunc arg1 arg2 ...”


在函數體中當中,可使用$1, $2, ...調用這些參數;還可以使用$@, $*, $#等特殊變量;


示例:添加10個用戶

#!/bin/bash
#
function adduser {
   if [ $# -lt 1 ]; then
return 2
# 2: no arguments
   fi
   if id $1 &> /dev/null; then
echo "$1 exists."
return 1
   else
useradd $1
[ $? -eq 0 ] && echo "Add $1 finished." && return 0
   fi
}
for i in {1..10}; do
    adduser myuser$i
done


練習:打印NN乘法表,使用函數實現;


變量作用域:

本地變量:當前shell進程;爲了執行腳本會啓動專用的shell進程;因此,本地變量的作用範圍是當前shell腳本程序文件;

局部變量:函數的生命週期;函數結束時變量被自動銷燬;

如果函數中有局部變量,其名稱同本地變量;


在函數中定義局部變量的方法:

local NAME=VALUE


函數遞歸:

函數直接或間接調用自身;


N!=N(n-1)(n-2)...1

n(n-1)! = n(n-1)(n-2)!

#!/bin/bash
#
fact() {
    if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
    else
echo $[$1*$(fact $[$1-1])]
    fi
}
fact 5



練習:求n階斐波那契數列;

#!/bin/bash
#
fab() {
    if [ $1 -eq 1 ]; then
echo 1
    elif [ $1 -eq 2 ]; then
echo 1
    else
echo $[$(fab $[$1-1])+$(fab $[$1-2])]
    fi
}
fab 7



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章