欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

创建函数

程序员文章站 2022-06-11 22:49:23
...

基本脚本函数

函数是一个脚本代码块,你可以为其命名并在代码中任何位置重用。

创建函数

第一种格式:

function name{
	commands
}

第二种格式:

name(){
commands
}

使用函数

#!/bin/bash
#...

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."

函数定义需在函数调用之前。函数命必须是唯一的,如果重定义了函数,新定义会覆盖原来函数的定义。

返回值

函数运行结束时会返回一个退出状态码。

默认退出状态码

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

#!/bin/bash
#...
func1(){
	echo "trying to display a non-existent file"
	ls -l badfile
}

echo "testing the function"
func1
echo "The exit statue is: $?"

函数的退出状态码是1。

#!/bin/bash
#...
func1(){
	ls -l badfile
	echo "trying to display a non-existent file"
}

echo "testing the function"
func1
echo "The exit statue is: $?"

该函数的退出状态码是0,尽管其中有一条命令并没有正常运行,所以使用函数的默认退出状态码是很危险的。

使用 return 命令

return 命令允许指定一个整数来定义函数的退出状态码。

#!/bin/bash
#...
function db1{
	read -p "Enter a value: " value
	echo "doubling the value"
	return $[ $value * 2 ]
}
db1
echo "The new value is $?"

db1 函数会将 $value 变量中用户输入的值翻倍,然后用 return 命令返回结果,脚本 $? 变量显示了该值。

但当用这种方法从函数中返回值时,要小心了。

  • 函数结束就取返回值。
  • 退出状态码必须是0~255。

如果在 ?? 变量之前执行了其他命令,函数的返回值就会丢失,记住,? 变量会返回执行的最后一条命令的退出状态码。

使用函数输出

可以支持浮点、字符串和整数。

#!/bin/bash
#...
function db1{
	read -p "Enter a value: " value # 并不作为STDOUT输出的一部分
	echo $[ $value * 2 ]
}

result=$(db1)
echo "The new value is $result"

在函数中使用变量

向函数传递参数

函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。例如,函数名会在$0变量中定义,函数命令行上的任何参数都会通过$1、22等定义,也可以用特殊变量#来判断传给函数的参数数目。

func1 $value1 10
#!/bin/bash
#...

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 "Let's try adding no number:"
value=$(addem)
echo $value
echo -n "Let's try adding three number:"
value=$(addem 10 15 20)
echo $value

首先检查参数,如果参数非法则返回-1。
**由于函数使用特殊参数环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值。**尽管函数也是用了$1和$2变量,但它们和脚本主体中的$1和$2变量并不相同。要在函数使用这些值,必须在调用函数时手动将它们传过去。

在函数中处理变量

函数使用两种类型的变量:

  • 全局变量
  • 局部变量

全局变量

全局变量是 shell 脚本中任何地方都有效的变量。默认情况下,你在脚本中定义的任何变量都是全局变量,在函数外定义的变量可在函数内正常访问。

#!/bin/bash
#...

function db1{
	value=$[ $value * 2 ]
}

read -p "Enter a value: " value
db1
echo "The new value is: " $value

$value 变量在函数外定义并赋值,当db1函数被调用时,该变量及其在函数中都依然有效,如果变量在函数内被赋予了新值,那么脚本中引用该变量时,新值也依然有效。

局部变量

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

local temp
local temp=$[ $value + 5 ]

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

数组变量和函数

向函数传数组参数

#!/bin/bash
#...

function testit{
	echo "The parameter are: [email protected]"
	thisarray=$1
	echo "The received array is $[thisarray[*]]"
}

myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
testit $myarray

The original array is: 1 2 3 4 5
The parameters are: 1
The received array is 1

如果你试图将该数组变量作为函数参数,函数只会取数组变量的第一个值。

#!/bin/bash
#...

function testit{
	local newarry
	newarray=(;'echo "[email protected]"')
	echo "The new array value is ${thisarray[*]}"
}

myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
testit ${myarray[*]}

The original array is: 1 2 3 4 5
The new array value is: 1 2 3 4 5
#!/bin/bash
#...

function testit{
	local sum=0
	local newarry
	newarray=($('echo "[email protected]"'))
	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)

从函数返回数组

function arraydblr{
	local origarray
	local newarray
	local elements
	local i
	origarray=($(echo "[email protected]"))
	newarray=($(echo "[email protected]"))
	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[*]}"

函数递归

计算阶乘:

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

创建库

在多个脚本中使用同一段代码。使用函数库文件来解决,然后在多个脚本中引用该库文件。

  1. 创建一个包含脚本中所需函数的共用库文件。
# myfuncs
function addem{
	echo $[ $1 + $2 ]
}

function multem{
	#...
}

function divem{
	#...
}
  1. 在脚本中导入库文件

shell 函数仅在定义它的 shell 会话内有效,如果你在 shell 命令行界面的提示符下运行 myfuncs shell 脚本,shell 会创建一个新的 shell 并在其中运行这个脚本,它会未那个新 shell 定义这三个函数。
使用函数库的关键在于 source 命令。source命令会在当前 shell 上下文中执行命令,而不是创建一个新的 shell。要在 shell 脚本中运行 myfuncs 库文件,只需要添加下面这行:

. ./myfuncs

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

. ./myfuncs

value1=10
value2=5
result=$(addem $value1 $value2)

在命令行上使用函数

一旦在 shell 中定义了函数,你就可以在整个系统中使用它了,无需担心脚本是不是在PATH环境变量里。

在命令行上创建函数

  1. 单行定义函数
$ function divem ( echo $[ $1 / $2 ]; )
$ divem 100 5
20
  1. 多行定义函数
$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10

如果函数名称和某内建函数名称相同,则会覆盖内建函数原有方法。

在 .bashrc 文件中定义函数

命令行上定义的 shell 函数当退出 shell 时,函数就消失了。

直接定义函数

直接将你写的函数放在文件末尾即可。

读取函数文件

利用 source 命令将库文件中的函数添加到你的 .bashrc 脚本中。

#.bashrc

#...

. /home/rich/libraries/myfuncs

shell 会将定义好的函数传给子 shell 进程。

实例

相关标签: # 高级shell脚本