Shell Script 函数

创建函数

有两种格式可以用来在bash shell脚本中创建函数

function name {
commands
}
name() {
commands
}

要在脚本中使用函数,只需要像其他shell命令一样,在行中指定函数名就行了。如果在函数被定义前使用函数,你会收到一条错误消息。

#!/bin/bash
function func1 {
echo "This is an example of a function"
}
func1
echo "Now this is the end of the script"

返回值

bash shell会把函数当作一个小型脚本,运行结束时会返回一个退出状态码。有3种不同的方法来为函数生成退出状态码。

  • 默认退出状态码

默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码。 

#!/bin/bash
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
func1
echo "The exit status is: $?"
$
$ ./test4
trying to display a non-existent file
ls: badfile: No such file or directory
The exit status is: 1            #函数的退出状态码是1,这是因为函数中的最后一条命令没有成功运行

但你无法知道函数中其他命令中是否成功运行。 

func1() {
ls -l badfile
echo "This was a test of a bad command"
}    #函数的退出状态码就是0,尽管其中有一条命令并没有正常运行
  • return 

使用return命令来退出函数并返回特定的退出状态码。return命令允许指定一个整数值来定义函数的退出状态码

#!/bin/bash
function dbl {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]        #退出状态码必须是0~255
}
dbl
echo "The new value is $?"    #,$?变量会返回执行的最后一条命令的退出状态码
  • 函数输出

正如可以将命令的输出保存到变量中一样,你也可以对函数的输出采用同样的处理办法。新函数会用echo语句来显示计算的结果。该脚本会获取dbl函数的输出,而不是查看退出状态码。

function dbl {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(dbl)

在函数中使用变量

  • 向函数传递参数

函数名会在$0变量中定义,函数命令行上的任何参数都会通过$1、$2等定义。也可以用特殊变量$#来判断传给函数的参数数目。

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

尽管函数也使用了$1和$2变量,但它们和脚本主体中的$1和$2变量并不相同。要在函数中使用这些值,必须在调用函数时手动将它们传过去。

function func7 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
    value=$(func7 $1 $2)
    echo "The result is $value"
else
    echo "Usage: badtest1 a b"
fi
  • 全局变量

全局变量是在shell脚本中任何地方都有效的变量。如果你在脚本的主体部分定义了一个全局变量,那么可以在函数内读取它的值。类似地,如果你在函数内定义了一个全局变量,可以在脚本的主体部分读取它的值。

function dbl {
value=$[ $value * 2 ]                #读取函数外全局
}
read -p "Enter a value: " value    
dbl
echo "The new value is: $value"    #读取函数内全局
  • 局部变量

local关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名字的变量,那么shell将会保持这两个变量的值是分离的。

function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
    echo "temp is larger"
else
    echo "temp is smaller"
fi

函数递归

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
$

函数库

bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。第一步是创建一个包含脚本中所需函数的公用库文件

$ 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
}
$

source命令会在当前shell上下文中执行命令,而不是创建一个新shell。可以用source命令来在shell脚本中运行库文件脚本。这样脚本就可以使用库中的函数了。
source命令有个快捷的别名,称作点操作符(dot operator)。要在shell脚本中运行myfuncs库文件,只需添加下面这行:

. ./myfuncs 

这个例子假定myfuncs库文件和shell脚本位于同一目录。如果不是,你需要使用相应路径访问该文件

$ cat test14
#!/bin/bash
# using functions defined in a library file
. ./myfuncs
[...]

在命令行上使用函数

  • 在命令行上创建函数

一种方法是采用单行方式定义函数。当在命令行上定义函数时,你必须记得在每个命令后面加个分号,这样shell就能知道在哪里是命令的起止了

$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
20
$ function doubleit { read -p "Enter value: " value; echo $[
$value * 2 ]; }
$
$ doubleit
Enter value: 20
40
$

另一种方法是采用多行方式来定义函数。在定义时,bash shell会使用次提示符来提示输入更多命令。

$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10
$
  • 在.bashrc 文件中定义函数

可以直接在主目录下的.bashrc文件中定义函数。许多Linux发行版已经在.bashrc文件中定义了一些东西,所以注意不要误删了。把你写的函数放在文件末尾就行了。

$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
. /etc/bashrc
fi
function addem {
echo $[ $1 + $2 ]
}
$

也可以用source命令(或者它的别名点操作符)将库文件中的函数添加到你的.bashrc脚本中

$ cat .bashrc
# .bashrc
# Source global definitions
if [ -r /etc/bashrc ]; then
    . /etc/bashrc
fi
. /home/rich/libraries/myfuncs
$

猜你喜欢

转载自blog.csdn.net/linshuo1994/article/details/84197735