创建Bash函数

基本的脚本函数

创建函数

有两种格式可以用来在bash shell脚本中创建函数。第一种格式采用关键字function,后跟分配给该代码块的函数名。

function name {
	commands
}

name属性定义了赋予函数的唯一名称。脚本中定义的每个函数都必须有一个唯一的名称。
commands是构成函数的一条或多条bash shell命令。在调用该函数时, bash shell会按命令在函数中出现的顺序依次执行,就像在普通脚本中一样。
在bash shell脚本中定义函数的第二种格式更接近于其他编程语言中定义函数的方式。

name() {
	commands
}

函数名后的空括号表明正在定义的是一个函数。这种格式的命名规则和之前定义shell脚本函数的格式一样。

使用函数

要在脚本中使用函数,只需要像其他shell命令一样,在行中指定函数名就行了。

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

每次引用函数名func1时, bash shell会找到func1函数的定义并执行你在那里定义的命令。函数定义不一定非得是shell脚本中首先要做的事,但一定要小心。如果在函数被定义前使用函数,你会收到一条错误消息。

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

第一个函数func1的定义出现在脚本中的几条语句之后,这当然没任何问题。当func1函数在脚本中被使用时, shell知道去哪里找它。
然而,脚本试图在func2函数被定义之前使用它。由于func2函数还没有定义,脚本运行函数调用处时,产生了一条错误消息。
你也必须注意函数名。记住,函数名必须是唯一的,否则也会有问题。如果你重定义了函数,新定义会覆盖原来函数的定义,这一切不会产生任何错误消息。

返回值

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

默认退出状态码

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

$ 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

函数的退出状态码是1,这是因为函数中的最后一条命令没有成功运行。但你无法知道函数中其他命令中是否成功运行。看下面的例子。

$ cat test4b
#!/bin/bash
# testing the exit status of a function
func1() {
	ls -l badfile
	echo "This was a test of a bad command"
}
echo "testing the function:"
func1
echo "The exit status is: $?"

$ ./test4b
testing the function:
ls: badfile: No such file or directory
This was a test of a bad command
The exit status is: 0

这次,由于函数最后一条语句echo运行成功,该函数的退出状态码就是0,尽管其中有一条命令并没有正常运行。使用函数的默认退出状态码是很危险的。幸运的是,有几种办法可以解决这个问题。

使用 return 命令

bash shell使用return命令来退出函数并返回特定的退出状态码。 return命令允许指定一个整数值来定义函数的退出状态码,从而提供了一种简单的途径来编程设定函数退出状态码。

$ 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 ]
}
$ dbl
echo "The new value is $?"

dbl函数会将$value变量中用户输入的值翻倍,然后用return命令返回结果。脚本用$?变量显示了该值。
但当用这种方法从函数中返回值时,要小心了。记住下面两条技巧来避免问题:
 记住,函数一结束就取返回值;
 记住,退出状态码必须是0~255。

如果在用$?变量提取函数返回值之前执行了其他命令,函数的返回值就会丢失。记住, $?变量会返回执行的最后一条命令的退出状态码。
第二个问题界定了返回值的取值范围。由于退出状态码必须小于256,函数的结果必须生成一个小于256的整数值。任何大于256的值都会产生一个错误值。

$ ./test5
Enter a value: 200
doubling the value
The new value is 1

要返回较大的整数值或者字符串值的话,你就不能用这种返回值的方法了。

使用函数输出

正如可以将命令的输出保存到shell变量中一样,你也可以对函数的输出采用同样的处理办法。可以用这种技术来获得任何类型的函数输出,并将其保存到变量中:

result='dbl'

这个命令会将dbl函数的输出赋给$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

$ ./test5b
Enter a value: 1000
The new value is 2000

新函数会用echo语句来显示计算的结果。该脚本会获取dbl函数的输出,而不是查看退出状态码。
这个例子中演示了一个不易察觉的技巧。你会注意到dbl函数实际上输出了两条消息。 read命令输出了一条简短的消息来向用户询问输入值。 bash shell脚本非常聪明, 并不将其作为STDOUT输出的一部分,并且忽略掉它。如果你用echo语句生成这条消息来向用户查询,那么它会与输出值一起被读进shell变量中。

说明 通过这种技术,你还可以返回浮点值和字符串值。这使它成为一种获取函数返回值的强大方法。

在函数中使用变量

向函数传递参数

bash shell会将函数当作小型脚本来对待。这意味着你可以像普通脚本那样向函数传递参数。
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在$0变量中定义,函数命令行上的任何参数都会通过$1、 $2等定义。也可以用特殊变量$#来判断传给函数的参数数目。
在脚本中指定函数时,必须将参数和函数放在同一行,像这样:

func1 $value1 10

然后函数可以用参数环境变量来获得参数值。这里有个使用此方法向函数传值的例子。

$ 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

test6脚本中的addem函数首先会检查脚本传给它的参数数目。如果没有任何参数,或者参数多于两个, addem会返回值-1。如果只有一个参数, addem会将参数与自身相加。如果有两个参数, addem会将它们进行相加。
由于函数使用特殊参数环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值。下面的例子将会运行失败。

$ cat badtest1
#!/bin/bash
# trying to access script parameters inside a function
function badfunc1 {
	echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
	value=$(badfunc1)
	echo "The result is $value"
else
	echo "Usage: badtest1 a b"
fi

$ ./badtest1
Usage: badtest1 a b
$ ./badtest1 10 15
./badtest1: * : syntax error: operand expected (error token is "*")
The result is

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

$ cat test7
#!/bin/bash
# trying to access script parameters inside a function
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

$ ./test7
Usage: badtest1 a b
$ ./test7 10 15
The result is 150

通过将$1和$2变量传给函数,它们就能跟其他变量一样供函数使用了。

在函数中处理变量

给shell脚本程序员带来麻烦的原因之一就是变量的作用域。作用域是变量可见的区域。函数中定义的变量与普通变量的作用域不同。也就是说,对脚本的其他部分而言,它们是隐藏的。
函数使用两种类型的变量:
 全局变量
 局部变量
下面几节将会介绍这两种类型的变量在函数中的用法。

1. 全局变量

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

$ cat test8
#!/bin/bash
# using a global variable to pass a value
function dbl {
	value=$[ $value * 2 ]
}
read -p "Enter a value: " value
dbl
echo "The new value is: $value"
$
$ ./test8
Enter a value: 450
The new value is: 900

$value变量在函数外定义并被赋值。当dbl函数被调用时,该变量及其值在函数中都依然有效。如果变量在函数内被赋予了新值,那么在脚本中引用该变量时,新值也依然有效。
但这其实很危险,尤其是如果你想在不同的shell脚本中使用函数的话。它要求你清清楚楚地知道函数中具体使用了哪些变量,包括那些用来计算非返回值的变量。这里有个例子可说明事情是如何搞砸的。

$ cat badtest2
#!/bin/bash
# demonstrating a bad use of variables
function func1 {
	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
$
$ ./badtest2
The result is 22
temp is larger

由于函数中用到了$temp变量,它的值在脚本中使用时受到了影响,产生了意想不到的后果。有个简单的办法可以在函数中解决这个问题,下节将会介绍。

2. 局部变量

无需在函数中使用全局变量,函数内部使用的任何变量都可以被声明成局部变量。要实现这一点,只要在变量声明的前面加上local关键字就可以了。

local temp

也可以在变量赋值语句中使用local关键字:

local temp=$[ $value + 5 ]

local关键字保证了变量只局限在该函数中。如果脚本中在该函数之外有同样名字的变量,那么shell将会保持这两个变量的值是分离的。现在你就能很轻松地将函数变量和脚本变量隔离开了,只共享需要共享的变量。

$ 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 ]
then
	echo "temp is larger"
else
	echo "temp is smaller"
fi

$ ./test9
The result is 22
temp is smaller

现在,在func1函数中使用$temp变量时,并不会影响在脚本主体中赋给$temp变量的值。

数组变量和函数

在函数中使用数组变量值有点麻烦,而且还需要一些特殊考虑。本节将会介绍一种方法来解决这个问题。

向函数传数组参数

向脚本函数传递数组变量的方法会有点不好理解。将数组变量当作单个参数传递的话,它不会起作用。

$ 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
The received array is 1

如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。下面是个具体的例子。

$ 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

该脚本用$myarray变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数组变量。在函数内部,数组仍然可以像其他数组一样使用。

$ 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

addarray函数会遍历所有的数组元素,将它们累加在一起。你可以在myarray数组变量中放置任意多的值, addarry函数会将它们都加起来。

从函数返回数组

从函数里向shell脚本传回数组变量也用类似的方法。函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。

$ 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

该脚本用$arg1变量将数组值传给arraydblr函数。 arraydblr函数将该数组重组到新的数组变量中,生成该输出数组变量的一个副本。然后对数据元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。
arraydblr函数使用echo语句来输出每个数组元素的值。脚本用arraydblr函数的输出来重新生成一个新的数组变量。

数组变量和函数

在函数中使用数组变量值有点麻烦,而且还需要一些特殊考虑。本节将会介绍一种方法来解决这个问题。

向函数传数组参数

向脚本函数传递数组变量的方法会有点不好理解。将数组变量当作单个参数传递的话,它不会起作用。

$ 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
The received array is 1

如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。要解决这个问题,你必须将该数组变量的值分解成单个的值,然后将这些值作为函数参数使用。在函数内部,可以将所有的参数重新组合成一个新的变量。下面是个具体的例子。

$ 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

该脚本用$myarray变量来保存所有的数组元素,然后将它们都放在函数的命令行上。该函数随后从命令行参数中重建数组变量。在函数内部,数组仍然可以像其他数组一样使用。

$ 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

addarray函数会遍历所有的数组元素,将它们累加在一起。你可以在myarray数组变量中放置任意多的值, addarry函数会将它们都加起来。

从函数返回数组

从函数里向shell脚本传回数组变量也用类似的方法。函数用echo语句来按正确顺序输出单个数组值,然后脚本再将它们重新放进一个新的数组变量中。

$ 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

该脚本用$arg1变量将数组值传给arraydblr函数。 arraydblr函数将该数组重组到新的数组变量中,生成该输出数组变量的一个副本。然后对数据元素进行遍历,将每个元素值翻倍,并将结果存入函数中该数组变量的副本。
arraydblr函数使用echo语句来输出每个数组元素的值。脚本用arraydblr函数的输出来重新生成一个新的数组变量。

函数递归

局部函数变量的一个特性是自成体系。除了从脚本命令行处获得的变量,自成体系的函数不需要使用任何外部资源。
这个特性使得函数可以递归地调用,也就是说,函数可以调用自己来得到结果。通常递归函数都有一个最终可以迭代到的基准值。许多高级数学算法用递归对复杂的方程进行逐级规约,直到基准值定义的那级。
递归算法的经典例子是计算阶乘。一个数的阶乘是该数之前的所有数乘以该数的值。因此,要计算5的阶乘,可以执行如下方程:
5! = 1 * 2 * 3 * 4 * 5 = 120
使用递归,方程可以简化成以下形式:
x! = x * (x-1)!
也就是说, x的阶乘等于x乘以x1的阶乘。这可以用简单的递归脚本表达为:

function factorial {
	if [ $1 -eq 1 ]
	then
		echo 1
	else
		local temp=$[ $1 - 1 ]
		local result='factorial $temp'
		echo $[ $result * $1 ]
	fi
}

阶乘函数用它自己来计算阶乘的值:

$ 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

使用阶乘函数很容易。创建了这样的函数后,你可能想把它用在其他脚本中。接下来,我们来看看如何有效地利用函数。

创建库

使用函数可以在脚本中省去一些输入工作,这一点是显而易见的。但如果你碰巧要在多个脚本中使用同一段代码呢?显然,为了使用一次而在每个脚本中都定义同样的函数太过麻烦。
有个方法能解决这个问题!bash shell允许创建函数库文件,然后在多个脚本中引用该库文件。这个过程的第一步是创建一个包含脚本中所需函数的公用库文件。这里有个叫作myfuncs的库文件,它定义了3个简单的函数。

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

下一步是在用到这些函数的脚本文件中包含myfuncs库文件。从这里开始,事情就变复杂了。问题出在shell函数的作用域上。和环境变量一样, shell函数仅在定义它的shell会话内有效。如果你在shell命令行界面的提示符下运行myfuncs shell脚本, shell会创建一个新的shell并在其中运行这个脚本。它会为那个新shell定义这三个函数,但当你运行另外一个要用到这些函数的脚本时,它们是无法使用的。
这同样适用于脚本。如果你尝试像普通脚本文件那样运行库文件,函数并不会出现在脚本中。

$ cat badtest4
#!/bin/bash
# using a library file the wrong way
./myfuncs
result=$(addem 10 15)
echo "The result is $result"
$
$ ./badtest4
./badtest4: addem: command not found
The result is

使用函数库的关键在于source命令。 source命令会在当前shell上下文中执行命令,而不是创建一个新shell。可以用source命令来在shell脚本中运行库文件脚本。这样脚本就可以使用库中的函数了。
source命令有个快捷的别名,称作点操作符(dot operator)。要在shell脚本中运行myfuncs库文件,只需添加下面这行:
. ./myfuncs
这个例子假定myfuncs库文件和shell脚本位于同一目录。如果不是,你需要使用相应路径访问该文件。这里有个用myfuncs库文件创建脚本的例子。

$ 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
The result of multiplying them is: 50
The result of dividing them is: 2

该脚本成功地使用了myfuncs库文件中定义的函数。

在命令行上使用函数

可以用脚本函数来执行一些十分复杂的操作。有时也很有必要在命令行界面的提示符下直接使用这些函数。
和在shell脚本中将脚本函数当命令使用一样,在命令行界面中你也可以这样做。这个功能很不错,因为一旦在shell中定义了函数,你就可以在整个系统中使用它了,无需担心脚本是不是在PATH环境变量里。重点在于让shell能够识别这些函数。有几种方法可以实现。

在命令行上创建函数

因为shell会解释用户输入的命令,所以可以在命令行上直接定义一个函数。有两种方法。
一种方法是采用单行方式定义函数。

$ function divem { echo $[ $1 / $2 ]; }
$ divem 100 5
20

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

$ 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

在函数的尾部使用花括号, shell就会知道你已经完成了函数的定义。

警告 在命令行上创建函数时要特别小心。如果你给函数起了个跟内建命令或另一个命令相同的名字,函数将会覆盖原来的命令。

在.bashrc 文件中定义函数

在命令行上直接定义shell函数的明显缺点是退出shell时,函数就消失了。对于复杂的函数来说,这可是个麻烦事。
一个非常简单的方法是将函数定义在一个特定的位置,这个位置在每次启动一个新shell的时候,都会由shell重新载入。
最佳地点就是.bashrc文件。 bash shell在每次启动时都会在主目录下查找这个文件,不管是交互式shell还是从现有shell中启动的新shell。

1. 直接定义函数

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

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

该函数会在下次启动新bash shell时生效。随后你就能在系统上任意地方使用这个函数了。

2. 读取函数文件

只要是在shell脚本中,都可以用source命令(或者它的别名点操作符)将库文件中的函数添加到你的.bashrc脚本中。

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

要确保库文件的路径名正确,以便bash shell能够找到该文件。下次启动shell时,库中的所有函数都可在命令行界面下使用了。

$ addem 10 5
15
$ multem 10 5
50
$ divem 10 5
2

更好的是, shell还会将定义好的函数传给子shell进程,这样一来,这些函数就自动能够用于该shell会话中的任何shell脚本了。你可以写个脚本,试试在不定义或使用source的情况下,直接使用这些函数。

$ cat test15
#!/bin/bash
# using a function defined in the .bashrc file
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"
$
$ ./test15
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2

甚至都不用对库文件使用source,这些函数就可以完美地运行在shell脚本中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值