您的位置:首页 > 运维架构 > Shell

shell脚本编程-函数

2015-09-27 18:19 686 查看
一、函数的定义和调用

二、函数的返回值

三、带参数的函数

四、自定义函数库

五、functions函数库

六、递归函数

一、函数的定义和调用

  函数是Shell脚本中自定义的一系列执行命令,一般来说函数应该设置返回值.

  语法:

#shell中的函数定义
#其中function为关键字,FUNCTION_NAME为函数名
funciton FUNCTON_NAME(){
command1 #函数体中可以有多个语句,不允许有空语句
command2
...
}
#省略关键字function,效果一样
FUNCTION_NAME(){
command1
command2
...
}


  eg:

[rhat@localhost shell]$ vim sayHello.sh
#!/bin/bash
function sayHello(){
echo "Hello"
}
echo "Call function sayHello"
sayHello
[rhat@localhost shell]$ sh ./sayHello.sh
Call function sayHello
Hello


  or

[rhat@localhost shell]$ vim countLine.sh
#!/bin/bash
FILE=/etc/passwd
function countLine(){
local i=0
while read line
do
let ++i
done < $FILE
echo "$FILE have $i lines"
}
echo "Call function countLine"
countLine
#执行结果
[rhat@localhost shell]$ sh ./countLine.sh
Call function countLine
/etc/passwd have 31 lines


二、函数的返回值

  函数的返回值又叫函数的返回状态,实际上是一种通信方式.获取上一个命令返回值得方式是使用$?

  eg:

[rhat@localhost shell]$ vim checkFileExist.sh
#!/bin/bash
FILE=/etc/notExistFile
function checkFileExist(){
if [ -f $FILE ];then
return 0
else
return 1
fi
}
echo "Call function checkFileExist"
checkFileExist    #调用函数
if [ $? -eq 0 ];then
echo "$FILE exist"
else
echo "$FILE not exist"
fi
#执行结果
[rhat@localhost shell]$ sh ./checkFileExist.sh
Call function checkFileExist
/etc/notExistFile not exist


  or

[rhat@localhost shell]$ vim checkNum.sh
#!/bin/bash
function checkNum(){
echo -n "Please input a number:"
read NUM
if [ $NUM -ge 0 -a $NUM -lt 10 ];then
return 0
fi
if [ $NUM -ge 10 -a $NUM -lt 20 ];then
return 1
fi
if [ $NUM -ge 20 -a $NUM -lt 30 ];then
return 2
fi
return 3
}
echo "Call function checkNum"
checkNum
RTV=$?
if [ $RTV -eq 0 ];then
echo "The number is between[0,10]"
elif [ $RTV -eq 1 ];then
echo "The number is between[10,20]"
elif [ $RTV -eq 2 ];then
echo "The number is between[20,30]"
else
echo "Unknown input"
fi
#执行结果
[rhat@localhost shell]$ sh ./checkNum.sh
Call function checkNum
Please input a number:30
Unknown input


三、带参数的函数

  向函数传递参数是使用位置参数来实现的.

[rhat@localhost shell]$ vim checkFileExist_v2.sh
#!/bin/bash
function checkFileExist(){
if [ -f $1 ];then
return 0
else
return 1
fi
}
echo "Call function checkFileExist"
checkFileExist $1
if [ $? -eq 0 ];then
echo "$FILE exist"
else
echo "$FILE not exist"
fi
#执行结果.
[rhat@localhost shell]$ sh ./checkFileExist_v2.sh haha.txt
Call function checkFileExist
not exist


  or

[rhat@localhost shell]$ vim power.sh
#!/bin/bash
function power(){
RESULT=1
LOOP=0
while [[ "$LOOP" -lt $2  ]]
do
let "RESULT=RESULT*$1"
let "LOOP+=1"
done
echo $RESULT
}
echo "Call function power with parameters"
power $1 $2
#执行结果
[rhat@localhost shell]$ sh ./power.sh 3 3
Call function power with parameters
27


  除了在脚本运行时给脚本传入位置参数外,还可以使用内置命令set命令给脚本指定位置参数的值.(又叫重置)

[rhat@localhost shell]$ vim set01.sh
#!/bin/bash
set 1 2 3 4 5 6
COUNT=1
for i in $@
do
echo "Here \$$COUNT is $i"
let "count++"
done
#执行结果
[rhat@localhost shell]$ sh ./set01.sh a b c d e f
Here $1 is 1
Here $1 is 2
Here $1 is 3
Here $1 is 4
Here $1 is 5
Here $1 is 6


  在shell中使用shift命令移动位置参数.shift命令可以让位置参数左移一位.

[rhat@localhost shell]$ vim shift03.sh
#!/bin/bash
until [ $# -eq 0 ]
do
echo "Now \$i is :$1,total parameter is:$#"
shift #加数字 2 表示 左移2个参数,eg: shift 2
done
#执行结果
[rhat@localhost shell]$ sh ./shift03.sh 1 2 3 a v c
Now $i is :1,total parameter is:6
Now $i is :2,total parameter is:5
Now $i is :3,total parameter is:4
Now $i is :a,total parameter is:3
Now $i is :v,total parameter is:2
Now $i is :c,total parameter is:1


四、自定义函数库

  对某些很常用的功能,必须考虑将其独立出来,集中存放在一些独立的文件中,这些文件就称为”文件库“,在实践中建议库函数使用下划线开头.

  eg:lib01.sh 函数库.

[rhat@localhost shell]$ vim lib01.sh
_checkFileExist(){
if [ -f $1 ];then
echo "File:$1 exist"
else
echo "File:$1 not exist"
7 }


  加载函数库的两种方式:

#使用”点“.命令。
[rhat@localhost shell]$ . ./lib01.sh      # / 前面的.表示当前目录,,别搞混。
#使用source命令。
[rhat@localhost shell]$ source ./lib01.sh


  脚本中调用函数库.

[rhat@localhost shell]$ vim callLib01.sh
#!/bin/bash
source ./lib01.sh            #引用函数库到当前shell.
_checkFileExist /etc/notExistFile
_checkFileExist /etc/passwd
#执行结果
[rhat@localhost shell]$ sh ./callLib01.sh
File:/etc/notExistFile not exist
File:/etc/passwd exist


五、函数库/etc/init.d/functions简介

  很多Linux发行版中都有/etc/init.d目录,这是系统中放置所有开机启动脚本的目录,这些开机脚本在脚本开始运行时都会加载/etc/init.d/functions 或/etc/rc.d/init.d/functionshanshuku.(两个库内容实际上完全一样. 如下:

# Source functions library
. /etc/init.d/functions
或者
# Source functions library
. /etc/rc.d/init.d/functions


  在脚本中使用functions函数库.

[rhat@localhost shell]$ vim callFunctions01.sh
#!/bin/bash
source /etc/init.d/functions
confirm ITEM    #confirm 实际上是functions库中的一个函数功能.
if [[ $? -eq 0 ]];then
echo "ITEM confirmed"
else
echo "ITEM not confirmed"
fi
#执行结果.
[rhat@localhost shell]$ sh ./callFunctions01.sh
Start service ITEM (Y)es/(N)o/(C)ontinue? [Y] y
ITEM confirmed


  functions库中常用的函数:

checkpid()检查某个PID是否存在
daemon()以deamon方式启动某个服务
killproc()停止某个进程
pidfileofproc()检查某个进程的PID文件
pidofproc()检查某个进程的PID
status()判断某个服务的状态
echo_success()打印OK
echo_failure()打印FAILED
echo_passed()打印PASSED
echo_warning()打印WARNING
success()打印OK并记录日志
failure()打印FAILED并记录日志
passed()打印PASSED并记录日志
warning()打印WARNING并记录日志
action()执行给定的命令,并根据执行结果打印信息
strstr()检查$1字符串中是否含有$2字符串
confirm()提示是否启动某个服务.
六、递归函数

  在函数中继续调用函数自身,注意调用条件,否则会毫无止境的调用,语法:

function recursion(){
recursion
confitionThatEndTheRecursion    #停止递归的条件.
}


  例如阶乘函数:n!=1x2x3x4x...xn.

[rhat@localhost shell]$ cat factorial01.sh
#!/bin/bash
function factorial01(){
local NUMBER=$1
if [ $NUMBER -le 0 ];then
RES=1
else
factorial01 $((NUMBER-1))
TEMP=$RES
NUMBER=$NUMBER
RES=$((NUMBER*TEMP))
fi
}
factorial01 $1
echo $RES
#执行结果
[rhat@localhost shell]$ sh -x ./factorial01.sh 4 #-x为观察执行过程的细节.
+ factorial01 4
+ local NUMBER=4
+ '[' 4 -le 0 ']'
+ factorial01 3
+ local NUMBER=3
+ '[' 3 -le 0 ']'
+ factorial01 2
+ local NUMBER=2
+ '[' 2 -le 0 ']'
+ factorial01 1
+ local NUMBER=1
+ '[' 1 -le 0 ']'
+ factorial01 0
+ local NUMBER=0
+ '[' 0 -le 0 ']'
+ RES=1
+ TEMP=1
+ NUMBER=1
+ RES=1
+ TEMP=1
+ NUMBER=2
+ RES=2
+ TEMP=2
+ NUMBER=3
+ RES=6
+ TEMP=6
+ NUMBER=4
+ RES=24
+ echo 24
24


  linux shell 汉诺塔实现:我没理解得了.((~﹃~)~zZ)

[rhat@localhost shell]$ vim hanoi01.sh
#!/bin/bash
function hanoi01(){
local num=$1
if [ "$num" -eq "1" ]; then
echo "Move:$2---->$4"
else
hanoi01 $((num-1)) $2 $4 $3
echo "Move:$2---->$4"
hanoi01 $((num-1)) $3 $2 $4
fi
}
hanoi01 4 A B C
#执行结果
[rhat@localhost shell]$ sh ./hanoi01.sh
Move:A---->B
Move:A---->C
Move:B---->C
Move:A---->B
Move:C---->A
Move:C---->B
Move:A---->B
Move:A---->C
Move:B---->C
Move:B---->A
Move:C---->A
Move:B---->C
Move:A---->B
Move:A---->C
Move:B---->C


  嵌套函数天生的结构就注定了其晦涩的可读性,在不少大公司内部的开发规范中也明确规定了不允许使用递归,所以在实际工作中药尽量避免使用递归.

返回顶部
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: