条件判断: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