在bash中是支持函数编写的,函数的作用就不言而喻了-一次定义,多处调用。调用函数时,只需输入给它的函数名即可。
我们将讨论如何创建自己的bash函数以及如何在shell脚本中使用它们。
一、创建函数
定义函数格式:
functioName() {
}
我们也可以使用fucntion
关键字来定义,但考虑posix
可移植性,不推荐使用该关键字。
function name() {
}
二、使用函数
myfunc() {
echo "我正在使用函数..."
}
total=1
while [ $total -le 3 ];do
myfunc
total=$(($total+1))
done
echo "结束循环"
myfunc
echo "结束脚本"
我们执行该脚本,输出结果如下:
我正在使用函数...
我正在使用函数...
我正在使用函数...
结束循环
我正在使用函数...
结束脚本
如果我们调用未定义的函数时,将会报错comand not found
,但脚本依然可以执行到尾行。
我们用两种方式定义函数,函数名相同,如下:
#!/bin/bash
myfunc() {
echo "The first function definition"
}
myfunc
function myfunc() {
echo "The second function definition"
}
myfunc
echo "End of the script"
上述代码,function
定义的函数名与第一种方式同名,它们不会报错,后定义的会覆盖掉先前定义的。执行结果如下:
The first function definition
The second function definition
End of the script
三、使用函数返回值
我们有两种方式来使用函数的返回值,我们先看第一种:
#!/bin/bash
myfunc() {
read -p "请输入一个数字:" value
echo "正在操作"
return $(($value+100))
}
myfunc
echo "新的value值为: $?"
我们执行它:
sh demo.sh
请输入一个数字:99
正在操作
新的value值为: 199
由此我们看出,函数的返回值为执行上一个命令的状态码,即return
值为状态码。
如果我们返回值不是数字,是字符串会怎么样?
myfunc(){
return 'hello'
}
#调用函数
myfunc
echo "新的value值为: $?"
line 5: return: hello: numeric argument required
新的value值为: 255
上述代码我们看到,函数内不允许返回字符串,返回字符串时,状态码为 255
注意:使用return作为返回值,最大值不能超过255,状态码最大值为
255
,表示状态码越界。
第二种方式使用函数返回值:
#!/bin/bash
myfunc() {
read -p "请输入一个数字:" value
echo "正在操作"
echo $(($value+100))
}
result=$(myfunc)
echo $result
注意:函数体内,我们使用了echo
,并不是return
,这时我们可以将函数名作为变量名使用。
四、传递参数
我们可以使用类似环境变量形式为函数传递参数。函数名声明为$0
变量,传递的参数为$1、$2、$3
等。
示例:
#!/bin/bash
addnum() {
if [ $# -gt 2 ]; then # $#表示参数个数
echo "请输入两个参数"
else
echo $(($1 + $2))
fi
}
echo "10 + 15: "
value=$(addnum 10 15)
echo $value
# 24
echo "测试三个参数:"
value=$(addnum 10 15 20)
echo $value
#请输入两个参数
当我们输入三个参数时,会提示我们输入两个参数。
我们来看一个错误
示例:
#!/bin/bash
myfunc() {
echo $(($1 + $2 + $3 + $4))
}
if [ $# -eq 4 ]; then
value=$(myfunc)
echo "Total= $value"
else
echo "请按照右边形式调用: myfunc a b c d"
fi
我们执行上述代码:sh demo.sh 1 2 3 4
,我们传入了四个参数,查看结果:
demo.sh: line 5: + + + : syntax error: operand expected (error token is " ")
Total=
代码执行错误,我们在执行demo.sh
时虽然传入了四个参数,但是在脚本中,我们想使用函数的返回值,但是在调用函数时,并未传入我们在执行脚本时的参数 ,导致函数体内的$1...
未定义。
我们改造一下 再调用sh demo.sh 1 2 3 4
:
#!/bin/bash
myfunc() {
echo $(($1 + $2 + $3 + $4))
}
if [ $# -eq 4 ]; then
value=$(myfunc $1 $2 $3 $4) #改造的代码
echo "Total= $value"
else
echo "请按照右边形式调用: myfunc a b c d"
fi
#执行结果为:Total =10
正确输出结果 10
五、在函数内使用变量
我们可以定义两种变量 :global
和local
我们先看global
,默认情况下,声明的任何变量都是全局变量。如果在函数之外定义变量,则在函数内调用它没有问题。
#!/bin/bash
myfunc() {
input=$(($input + 10))
}
read -p "请输入一个数字: " input
myfunc
echo "新的数字为: $input"
#我们输入数字 5,执行结果为 15
上述代码,我们执行脚本,然后输入数字 5,执行结果为15。在函数内部可以访问到外部的input
,并且外部的变量被更改为 15
local
变量使用:
#!/bin/bash
myfunc() {
local tmp=10
echo "函数内值: $tmp"
}
tmp=4
myfunc
echo "函数外值: $tmp"
函数内值: 10
函数外值: 4
我们在函数内部和外部定义了同名的两个变量,但结果互不影响。
六、使用数组作为函数参数
#!/bin/bash
myfunc() {
echo "所有参数: $@"
echo $1
echo $2
echo $3
}
my_arr=(5 10 15)
echo "原始数组的值为: ${my_arr[*]}"
myfunc ${my_arr[*]}
#执行结果
原始数组的值为: 5 10 15
所有参数: 5 10 15
5
10
15
我们将数组内所有值传递给函数,在函数内可以全部获取到数组内的值。
七、递归调用:
我们编写一个例子,实现某个数字的阶乘。
myfucn(){
if [ $1 -eq 1 ];then
echo 1
else
local next=$[$1-1]
local res=$(myfucn $next)
echo $(($res * $1))
fi
}
myfucn 5
#120
八、作为库文件被外部引用
我们编写A文件如下:
#!/bin/bash
addnum() {
echo $(($1 + $2))
}
编写B文件,并在B文件引入A:
#!/bin/bash
. ./A
echo $(addnum 10 20)
#输出结果 30
我们还可以将A文件的addnum作为一条命令来执行,首先我们编辑家目录里的.bashrc
文件,我们加入一行:
. /Users/houger/A
注意:开始位置有个点.
,不要省略掉,它的意思是加载脚本文件
接下来我们执行命令:addnum 10 20
,正确执行,输出结果30
参考:
往期: