一、函数功能
1. 结构化编程,不能独立运行需要调用时执行并可以被多次调用。
2. 函数为了代码最大程度地重用和最小化代码冗余而提供的基本程序结构。
3. 函数是一种设计工具,它能让程序员将复杂的系统分解为可管理的部件。
4. 函数用于将相关功能打包并参数化。
二、函数语法
有两种分别是:
1 2 3 4 |
function FUNCTION_NAME { command1... command2... } |
或
1 2 3 4 |
FUNCTION_NAME() { command1... command2... } |
在函数中是可以使用return命令,跟echo不同的是,return命令会使得一个函数返回某个变量,而不是像echo一样输出某个变量。其实在Shell中两者不太容易搞明白其区别,如果在Python语言中你就能体会出两者的差别了。在Shell中,一般我们需要函数返回值时,如果不用return作为返回值,函数就会直接将输出到标准输出中的内容作为返回值。因此,我们可以用这种方式,在函数中如果得到了某个想要作为返回值的变量,直接执行echo $varname,即可将这个变量的值作为函数值返回。
如果使用return作为返回值方式,这时,return一般配合$?使用。需要要注意的是,用return如果返回数字,只能返回整形,而标准输出的方法没有这个限制。
1 2 3 4 5 6 7 8 9 |
#!/bin/bash # main() { result=$(expr 1 + 4) return $result } main echo $? |
这种情况一般是先定义好函数,然后执行函数,最后用$?来获得函数返回值。这种方法的实质是返回函数中最后一条语句的返回值,因此在获得需要得到的变量的值以后,就可以用return $result的方法,将$result这条语句的返回值,也就是result的值,作为函数返回值。有时我们也可以在if的判断条件中直接调用函数,来判断函数是否执行成功。
另外,在函数中位置变量的使用跟在脚本中使用不同,如位置变量$1调用的是函数后面的第一个参数而不是执行脚本后面的第一个命令行参数。如下测试:
1 2 3 4 5 6 7 |
#!/bin/bash # main() { echo $# $0 $1 $2 } main |
执行这个脚本,会得到如下结果:
1 2 |
$ bash test.sh arg1 arg2 0 test.sh |
会发现,除了$0以外,其余都位置变量都获取不到值。这是因为我们传的命令行参数并不是赋予了函数,如果想得到正确结果,需要在函数后来同样传入相同的参数。
1 2 3 4 5 6 7 |
#!/bin/bash # main() { echo $# $0 $1 $2 } main $1 $2 |
再次执行就能得到正确结果:
1 2 |
$ bash test.sh arg1 arg2 2 test.sh arg1 arg2 |
这是在使用函数时需要特别注意的地方。
在函数中也是可以调用函数本身的,后面有一个实例,通过调用自己来实现阶乘。
三、实例
下面对于函数的使用,带来一些简单的示例。
1)查看硬件使用情况
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#!/bin/bash # function monitor{ echo " m|M:display Memory use status d|D :display Disk use status s|S :display Swap use status q|Q :quit " } monitor read -p -e 5 "Your choice:" CHOICE until [ $CHOICE='q' -o $CHOICE='Q' ]; do case $CHOICE in d|D) df -hP ;; s|S) free -m | grep "Swap" ;; m|M) free -m | grep "^Mem" ;; *) function read -p -e 5 "Your choice again:" CHOICE esac function read -p -e 5 "Your choice:" CHOICE done |
2)使用函数做阶乘
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
[root@localhost ~]# cat test.sh #!/bin/bash # JC=1 POS=$1 function test() { local LOCAL=$1 local LOCAL_N=$(($LOCAL - 1)) if [ $LOCAL_N -lt 1 ]; then JC=1 else test $LOCAL_N JC=`expr $LOCAL \* $JC` fi } test $POS echo $JC [root@localhost ~]# sh test.sh 5 |
PS:这个脚本用到了函数的上面说到的,函数的位置变量以及函数内调用函数本身。还用到了局部变量,正是因为局部变量这个阶乘才得以实现。
3)使用函数做类似Sysv风格的脚本服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#!/bin/bash # SCREEN=`stty -F /dev/console size 2> /dev/null` COLUMENS=80 SPACE_COL=$[ $COLUMENS-20 ] ##COLOR RED='\033[31m' GREEN='\033[32m' YELLOW='\033[33m' NORMAL='\033[0m' ##Funcaiton success() { REAL_SPACE=$[ $SPACE_COL - ${#1} ] echo -n "$1" for i in `seq 1 $REAL_SPACE`;do echo -n " " done echo -e "[ ${GREEN}0K${NORMAL} ]" } failure() { REAL_SPACE=$[ $SPACE_COL - ${#1} ] echo -n "$1" for i in `seq 1 $REAL_SPACE`; do echo -n " " done echo -e "[${RED}FAIL${NORMAL}]" } success "httpd is staring." failure "httpd is stopping." |
Shell本身比较简单,多多练习基本就能很熟练运用。