函数不管在那个编程语言中都有举足轻重的地位,在linux shell script中当然也不例外,下面我们就一起学习如何打造出功能强大的函数。
1.如何在script中创建一个函数,可以用以下两种方式:
A. function name
{
commands
}
B. name()
{
commands
}
你只需要挑选上面的一种喜欢的方式来实现你的函数即可。
2.如何使用函数?我们通过一个例子来理解:
- $ cat test1
- #!/bin/bash
- # using a function in a script
- function func1 {
- echo "This is an example of a function"
- } #这里创建了我们自己的函数
- count=1
- while [ $count -le 5 ] #此处实现调用函数n次,n=5
- do
- func1 #这里调用我们创建的函数,就像使用命令一样。
- count=$[ $count + 1 ]
- done
- echo "This is the end of the loop"
- func1
- echo "Now this is the end of the script"
- $ ./test1
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is the end of the loop
- This is an example of a function
- Now this is the end of the script
- $
当然这里需要大家注意,如果你试图在函数创建之前使用它会提示错误。 command not found.我们看下面的例子:
- $ cat test2
- #!/bin/bash
- # using a function located in the middle of a script
- count=1
- echo "This line comes before the function definition"
- function func1 {
- echo "This is an example of a function"
- }
- while [ $count -le 5 ]
- do
- func1
- count=$[ $count + 1 ]
- done
- echo "This is the end of the loop"
- func2 #在调用func2之前,函数还没有被创建,所以会报错。
- echo "Now this is the end of the script"
- function func2 {
- echo "This is an example of a function"
- }
- $ ./test2
- This line comes before the function definition
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is an example of a function
- This is the end of the loop
- ./test2: func2: command not found
- Now this is the end of the script
- $
还有一个需要注意的是,你必须保证每一个函数名称都是唯一的, 否则会发生你意想不到的问题,我们通过下面的例子:
- $ cat test3
- #!/bin/bash
- # testing using a duplicate function name
- function func1 {
- echo "This is the first definition of the function name"
- } #这里定义了一个func1
- func1
- function func1 {
- echo "This is a repeat of the same function name"
- } #这里出现了重复的定义func1
- func1 #以后只要是调用函数func1的地方,都会调用第二次的定义。
- echo "This is the end of the script"
- $ ./test3
- This is the first definition of the function name
- This is a repeat of the same function name
- This is the end of the script
- $
3.函数的返回值,请看下面的例子:
A.当函数没有明确定义返回值时,默认返回值是函数最后一条命令的执行返回值。
- $ cat test4
- #!/bin/bash
- # testing the exit status of a function
- func1() {
- echo "trying to display a non-existent file"
- ls -l badfile
- } #此函数没有明确定义返回值,因此它的返回值就是最后一条命令执行后的返回值。
- echo "testing the function:"
- func1
- echo "The exit status is: $?"
- $ ./test4
- testing the function:
- trying to display a non-existent file
- ls: badfile: No such file or directory
- The exit status is : 1 #因为badfile不存在,所以ls命令返回1
- $
B.我们可以通过return命令自己指定想要返回的值,但是这个返回值是有条件的,它必须是0-255之间的整数,如果不在此范围,将会自动返回一错误值,大家可以调式下面的例子:
- $ cat test5
- #!/bin/bash
- # using the return command in a function
- function dbl {
- read -p "Enter a value: " value
- echo "doubling the value"
- return $[ $value * 2 ] #这里是你指定的返回值,这个值是通过你输入的value值乘以2得到的,但它仍然要在0-255之间,否则返回错误值。(如何返回大于255的值我们后面会讲到)
- }
- dbl
- echo "The new value is $?"
- $ ./test5
- Enter a value: 200 #这里value=200
- doubling the value
- The new value is 1 #需要返回的值为400,大于255,所以返回一错误值。但这个错误值不一定是1。
请大家注意,既然return 能够主动从函数返回,所以return后面的语句将不被执行,你就别白费了。
4.使用函数的输出,你能够用一个脚本变量捕获函数的输出,就像捕获命令的输出一样,使用下面的语法:
result = `func1` #func1函数中的所有输出都将定向到result变量。请看下面的例子:
- $ cat test5b
- #!/bin/bash
- # using the echo to return a value
- function dbl {
- read -p "Enter a value: " value
- echo $[ $value * 2 ]
- }
- result=`dbl`
- echo "The new value is $result"
- $ ./test5b
- Enter a value: 200
- The new value is 400 #这里得到了函数大于255的返回值哦,-_-
- $ ./test5b
- Enter a value: 1000
- The new value is 2000
- $
5.如果你觉得上面的都懂了,那恭喜你,你已经有相当的功底了,我们继续往下看。
如何在函数中使用变量:
A. 我们可以通过参数传递给函数传递变量,就像给脚本传递参数一样,函数中使用参数也和脚本中一样,我们可以使用$1,$2,$3...得到参数值,可以通过$#得到参数个数,可以通过$*或$@得到所有的参数内容。我们通过下面的例子来理解:
- $ cat test6
- #!/bin/bash
- # passing parameters to a function
- function addem {
- if [ $ # -eq 0 ] || [ $# -gt 2 ]
- then
- echo -1
- elif [ $ # -eq 1 ]
- then
- echo $[ $1 + $ 1 ]
- else
- echo $[ $1 + $ 2 ]
- fi
- }
- echo -n "Adding 10 and 15: "
- value=`addem 10 15 `
- echo $value
- echo -n "Let’s try adding just one number: "
- value=`addem 10 `
- echo $value
- echo -n "Now trying adding no numbers: "
- value=`addem`
- echo $value
- echo -n "Finally, try adding three numbers: "
- value=`addem 10 15 20 `
- echo $value
- $ ./test6
- Adding 10 and 15 : 25
- Let’s try adding just one number: 20
- Now trying adding no numbers: -1
- Finally, try adding three numbers: - 1
- $
B. 学会使用全局变量与局部变量:
B1.你可以在脚本的任何地方定义全局变量,包括函数中,使用变量定义的语法即可:
variable=variable_value
B2.任何在函数内部使用的变量你都可以定义为局部变量,使用下面的语法即可:
local local_variable=variable_value
使用局部定义创建的局部变量只能在定义的函数内使用。我们看下面的例子:
- $ cat test9
- #!/bin/bash
- # demonstrating the local keyword
- function func1 {
- local temp=$[ $value + 5 ]
- result=$[ $temp * 2 ]
- }
- temp=4
- value=6
- func1
- echo "The result is $result"
- if [ $temp -gt $value ] #此处使用的temp的值将不会与函数和func1中的temp有任何关系。
- then
- echo "temp is larger"
- else
- echo "temp is smaller"
- fi
- $ ./test9
- The result is 22
- temp is smaller
- $
C.如何给函数传递数组参数,这是需要艺术的。
C1.如果你像传递单个参数那样给脚本传递数组,那么他将无法运行。看下面的例子:
- $ cat badtest3
- #!/bin/bash
- # trying to pass an array variable
- function testit {
- echo "The parameters are: $@"
- thisarray=$1
- echo "The received array is ${thisarray[*]}"
- }
- myarray=(1 2 3 4 5 )
- echo "The original array is: ${myarray[*]}"
- testit $myarray
- $ ./badtest3
- The original array is : 1 2 3 4 5
- The parameters are: 1
- ./badtest3: thisarray[*]: bad array subscript #也许你没有产生这个错误,但是我要说,你也只能获得数组的第一个值。
- The received array is
- $
C2.解决这个问题的方法是,我们可以把数组拆开成每个值,然后作为函数的参数值传递给函数,最后在函数内部我们把它再组合成数组使用。也许你觉得这个根本就是个笨的办法。但我们还是可以试试,看下面的例子:
- $ cat test10
- #!/bin/bash
- # array variable to function test
- function testit {
- local newarray
- newarray=(`echo "$@" `) #这里把函数的所有参数组合成一个数组。
- echo "The new array value is: ${newarray[*]}"
- }
- myarray=(1 2 3 4 5 )
- echo "The original array is ${myarray[*]}"
- testit ${myarray[*]} #这里我们把数组的每一个值都作为参数传递给了函数。
- $ ./test10
- The original array is 1 2 3 4 5
- The new array value is : 1 2 3 4 5
- $
我们再看一个使用数组的例子,最好是练习它:
- $ cat test11
- #!/bin/bash
- # adding values in an array
- function addarray {
- local sum=0
- local newarray
- newarray=(`echo "$@" `)
- for value in ${newarray[*]}
- do
- sum=$[ $sum + $value ]
- done
- echo $sum
- }
- myarray=(1 2 3 4 5 )
- echo "The original array is: ${myarray[*]}"
- arg1=`echo ${myarray[*]}`
- result=`addarray $arg1`
- echo "The result is $result"
- $ ./test11
- The original array is : 1 2 3 4 5
- The result is 15
- $
C3.如何返回一个数组,我们还是借用上面传递类似的方法,请看下面的例子:
- $ cat test12
- #!/bin/bash
- # returning an array value
- function arraydblr {
- local origarray
- local newarray
- local elements
- local i
- origarray=(`echo "$@" `)
- newarray=(`echo "$@" `)
- elements=$[ $# - 1 ]
- for (( i = 0 ; i <= $elements; i++ ))
- {
- newarray[$i]=$[ ${origarray[$i]} * 2 ]
- }
- echo ${newarray[*]}
- }
- myarray=(1 2 3 4 5 )
- echo "The original array is: ${myarray[*]}"
- arg1=`echo ${myarray[*]}`
- result=(`arraydblr $arg1`) #这里把函数的输出结果重新组合成数组
- echo "The new array is: ${result[*]}"
- $ ./test12
- The original array is : 1 2 3 4 5
- The new array is : 2 4 6 8 10
6.函数的递归操作,这种迭代操作一般都是基于一种存在情况,并且这种情况有特定的值。看下面的例子:
- $ cat test13
- #!/bin/bash
- # using recursion
- function factorial {
- if [ $ 1 -eq 1 ]
- then
- echo 1
- else
- local temp=$[ $1 - 1 ]
- local result=`factorial $temp` #此处进行迭代计算
- echo $[ $result * $1 ]
- fi
- }
- read -p "Enter value: " value
- result=`factorial $value`
- echo "The factorial of $value is: $result"
- $ ./test13
- Enter value: 5
- The factorial of 5 is : 120
- $
7.最后跟大家一起分享的是,创建自己的libary简化自己的脚本编写。
大家可以把自己经常使用的一些函数编写到一个固定的脚本中,然后在需要此中的函数时就先引用这个文件即可。
请用下面的语法引用:
../mylibary
示例:
- $ cat myfuncs
- # my script functions
- function addem {
- echo $[ $1 + $2 ]
- }
- function multem {
- echo $[ $1 * $2 ]
- }
- function divem {
- if [ $2 -ne 0 ]
- then
- echo $[ $1 / $2 ]
- else
- echo -1
- fi
- #下面新建一个脚本使用上面的函数
- $ cat test14
- #!/bin/bash
- # using functions defined in a library file
- . ./myfuncs
- value1=10
- value2=5
- result1=`addem $value1 $value2`
- result2=`multem $value1 $value2`
- result3=`divem $value1 $value2`
- echo "The result of adding them is: $result1"
- echo "The result of multiplying them is: $result2"
- echo "The result of dividing them is: $result3"
- $ ./test14
- The result of adding them is : 15
- } #创建了一个含有需要函数的脚本作为libary
- $
以上是我学习的一些笔记,希望跟大家一起分享探讨。
from http://blog.csdn.net/wesleyluo/archive/2010/02/08/5297558.aspx