一、shell脚本中的函数
(1)函数的创建
函数创建有两种方式,格式分别如下:注意name和后面的{有空格。
第一种:
function name {
commands
}
第二种:
name() {
commands
}
(2)函数的使用
在脚本中使用函数,直接指定函数名即可。需要注意的是函数在使用是必须先定义。
cat test.sh
#!/bin/bash
count=1
echo "this is a test"
function func1{
echo "this is a function"
}
while [ $count -le 5 ]
do
func1
count=$[$count+1]
done
echo "this is the end of loop"
func2
echo "now this is the end of the script"
function func2{
echo "this is a another test"
}
脚本运行的结果如下:
[root@~]# ./test.sh
this is a test
this is a function
this is a function
this is a function
this is a function
this is a function
this is the end of loop
./test.sh: line 18: func2: command not found
now this is the end of the script
由执行结果可见,func2函数在使用之前没有先定义,报错。
(3)返回值
bash shell把函数当作一个小型脚本,运行结束时会返回一个退出状态码。有3种不同的方式可以为函数生成退出状态码。
1.默认退出状态码
默认情况下,函数的退出状态码是函数中最后一条命令返回的退出状态码。在函数执行结束后,可以用标准变量$?来确定函数的退出状态码。但是这有一个弊端,就是无法知道函数中的所有命令是否都执行成功。
cat test.sh
#!/bin/bash
func1() {
ls -al filename
echo "this is a test"
}
func1
echo "the exit status is :$?"
执行结果为:
[root@~]# ./test.sh
ls: cannot access filename: No such file or directory
this is a test
the exit status is :0
由于函数的最有一条语句echo运行成功,函数的退出状态码为0,但是其中的ls -al命令是不成功的。使用函数的默认退出状态码是很危险的。
为了解决上述默认退出状态码的问题,bash shell提供了另外两种生成退出状态码的方式。
2.使用return命令
return命令允许指定一个整数值来定义函数的退出状态码。当使用这种方法时需要注意的两点:
函数一结束就取返回值;退出状态码必须是0~255。
如果在用$?变量提取函数返回值之前执行了其它命令,函数的返回值就会丢失。$?变量会返回执行的最后一条命令的退出状态码。
退出状态码必须小于256,函数的结果必须生成一个小与256的整数值。
cat test.sh
#!/bin/bash
function test {
read -p "enter a value: " value
echo "doubling the value"
return $[ $value *2 ]
}
test
echo "the new value is $?"
脚本的执行结果:
[root@~]# ./test.sh
enter a value: 3
doubling the value
the new value is 6
[root@~]# ./test.sh
enter a value: 200
doubling the value
the new value is 144
可以看到当value赋值为200时,200*2的值大于256,退出状态码不是期望的值。如果要返回较大的整数值或者字符串值,可以用下面的方法。
3.使用函数输出
正如可以将命令的输出保存到shell变量一样,也可以对函数的输出采用同样的处理方法。可以用这种方法获得任何类型的函数输出,并保存到变量中。
cat test.sh
#!/bin/bash
function func1 {
read -p "enter the value: " value
echo $[ $value *2 ]
}
result=`func1`
echo "the new value is $result"
脚本执行结果:
[root@~]# ./test.sh
enter the value: 200
the new value is 400
(4)在函数中使用变量
1.向函数传参
函数可以使用标准的参数环境变量来表示命令行上传给函数的参数。在脚本中执定函数时,必须将参数和函数放在同一行,例如:
func1 $value 10
cat test.sh
#!/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 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 13)
echo $value
执行结果:
[root@~]# ./test.sh
Adding 10 and 15: 25
let try adding just one number: 20
now trying adding no numbers: 1
finally,try adding three numbers: 1
由于函数使用特殊环境变量作为自己的参数值,因此它无法直接获取脚本在命令行中的参数值。
cat test.sh
#!/bin/bash
function func1 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(func1)
echo "the result is $value"
else
echo "usage:func1 a b"
fi
执行结果:
[root@~]# ./test.sh
usage:func1 a b
[root@~]# ./test.sh 10 15
./test.sh: line 3: * : syntax error: operand expected (error token is "* ")
the result is
虽然函数也使用了$1和$2变量,但他们在脚本主体中的$1和$2变量不一样。要在函数中使用这些值,必须在调用函数时手动传过去。
cat test.sh
#!/bin/bash
function func1 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(func1 $1 $2)
echo "the result is $value"
else
echo "usage:func1 a b"
fi
执行结果如下:
[root@~]# ./test.sh
usage:func1 a b
[root@~]# ./test.sh 10 10
the result is 100
2.在函数中处理变量
函数使用两种类型的变量:全局变量和局部变量。
默认情况下,在脚本张定义的任何变量都是全局变量。在函数外定义的变量可在函数内正常访问。
需要注意的是,如果变量在函数内被赋予了新值,那么在脚本中引用该变量时,新值也依然有效。
cat test.sh
#!/bin/bash
function func1 {
temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=6
value=10
func1
echo "the result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
执行结果如下:
[root@~]# ./test.sh
the result is 30
temp is larger
由于函数中用到了$temp变量,它的值在脚本中使用时受到了影响,产生了意想不到的后果。为了解决这个问题,我们可以在函数中使用局部变量。
局部变量:函数内部使用的任何变量都可以被声明为局部变量,只需要在变量名前加上关键字,local。
cat test.sh
#!/bin/bash
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=6
value=10
func1
echo "the result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
执行结果:
[root@~]# ./test.sh
the result is 30
temp is smaller
从结果可以知道,函数func1中使用$temp变量时,并不会影响在脚本主体中赋给变量$temp的值。