函数:function
过程式编程:代码重用
模块化编程
结构化编程
把一段独立功能的代码当作一个整体,并为之一个名字;命名的代码段,此即为函数;
注意:定义函数的代码段不会自动执行,在调用时执行;所谓调用函数,在代码中给定函数名即可;
函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;
语法一:
function f_name {
...函数体...
}
语法二:
f_name() {
...函数体...
}
函数的生命周期:每次被调用时创建,返回时终止;
其状态返回结果为函数体中运行的最后一条命令的状态结果;
自定义状态返回值,需要使用:return
return [0-255]
0: 成功
-255: 失败
示例:给定一个用户名,取得用户的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 ;; stop) stop ;; restart) stop start ;; status) status ;; *) usage exit 1 ;; esac
函数返回值:
函数的执行结果返回值:
(1) 使用echo或printf命令进行输出;
(2) 函数体中调用的命令的执行结果;
函数的退出状态码:
(1) 默认取决于函数体中执行的最后一条命令的退出状态码;
(2) 自定义:return
函数可以接受参数:
传递参数给函数:
在函数体中当中,可以使用$1,$2, ...引用传递给函数的参数;还可以函数中使用$*或[email protected]引用所有参数,$#引用传递的参数的个数;
在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,testfunc arg1 arg2 arg3 ...
示例:添加10个用户,
添加用户的功能使用函数实现,用户名做为参数传递给函数;
#!/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
变量作用域:
局部变量:作用域是函数的生命周期;在函数结束时被自动销毁;
定义局部变量的方法:local VARIABLE=VALUE
本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用范围为当前shell脚本程序文件;
示例程序:
#!/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*(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 $1
实现如下数列:
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