shell函数(调⽤、返回值,返回值获取)
Shell函数返回值,常⽤的两种⽅式:return,echo
1) return 语句shell函数的返回值,可以和其他语⾔的返回值⼀样,通过return语句返回。
⽰例1:
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$ #!/bin/sh
[devadmin@swarm1 pos-gateway]$ function mytest()
> {
> echo"arg1 = $1"
> if [ $1 = "1" ] ;then
> return 'ret1'
> else
> return 'ret0'
> fi
> }
[devadmin@swarm1 pos-gateway]$ mytest 1
shell代码arg1 = 1
-bash: return: ret1: numeric argument required
[devadmin@swarm1 pos-gateway]$
“numeric argument required”错误:
Shell 函数返回值只能是整形数值,⼀般是⽤来表⽰函数执⾏成功与否的,0表⽰成功,其他值表⽰失
败。因⽽⽤函数返回值来返回函数执⾏结果是不合适的。如果要硬⽣⽣地return某个计算结果,⽐如⼀个字符串,往往会得到错误提⽰:“numeric
argument required”。
如果⼀定要让函数返回⼀个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地⽅通过访问全局变量,就可以获得那个函数“返回”的⼀个或多个执⾏结果了。
重新修改下⽰例2:
[devadmin@swarm1 pos-gateway]$ function mytest() { echo"arg1 = $1" ; if [ $1 = "1" ] ;then return 100; else return 200; fi ; } [devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$
[devadmin@swarm1 pos-gateway]$ mytest 1
arg1 = 1
[devadmin@swarm1 pos-gateway]$ echo $?
100
[devadmin@swarm1 pos-gateway]$ mytest 2
arg1 = 2
[devadmin@swarm1 pos-gateway]$ echo $?
200
[devadmin@swarm1 pos-gateway]$
⽰例3:
[devadmin@swarm1 pos-gateway]$ if mytest 1; then
> echo"mytest 1"
> fi
arg1 = 1
[devadmin@swarm1 pos-gateway]$
说明:先定义了⼀个函数mytest,根据它输⼊的参数是否为1来return 100或者return 200。
A、如何调⽤shell函数(执⾏函数):函数名参数
B、获取shell函数结果:$?
C、另外,可以直接⽤函数的返回值⽤作if的判断。(⽰例3)
注意:return只能⽤来返回整数值,且和c的区别是返回为正确,其他的值为错误。
2) argv全局变量
这种就类似于中的全局变量(或环境变量)。
⽰例:
#!/bin/bash -
function mytest2()
{
echo"mytest2"
echo"args $1"
g_var=$1
return 0
}
mytest2 1
echo"return $?"
echo
echo"g_var=$g_var"
结果:
mytest2
args 1
return 0
g_var=1
函数mytest2通过修改全局变量(g_var)的值,来返回结果。
注:以上两个⽅法失效的时候,以上介绍的这两种⽅法在⼀般情况下都是好使的,但也有例外。⽰例:
#!/bin/bash -
function mytest3()
{
grep"123" | awk -F: '{print $2}' | while read line ;do
echo"$line"
if [ $line = "yxb" ]; then
return 0 # return to pipe only
fi
done
echo"mytest3 here "
return 1 # return to main process
}
g_var=
function mytest4()
{
grep"123" | awk -F: '{print $2}' | while read line ;do
echo"$line"
if [ $line = "yxb" ]; then
g_var=0
echo"g_var=0"
return 0 # return to pipe only
fi
done
echo"mytest4 here "
return 1
}
mytest3
echo $?
echo
mytest4
echo $?
echo
echo"g_var=$g_var"
其中, ⽂件中的内容如下:
456:kkk
123:yxb
123:test
结果:
yxb
1
yxb
g_var=0
mytest4 here
1
g_var=
可以看到mytest3在return了以后其实没有直接返回,⽽是执⾏了循环体后的语句,同时看到mytest4中也是⼀样,同时,在mytest4中,对全局变量的修改也⽆济于事,全局变量的值根本就没有改变。这个是什么原因那?
笔者认为,之所以return语句没有直接返回,是因为return语句是在管道中执⾏的,管道其实是另⼀个⼦进程,⽽return只是从⼦进程中返回⽽已,只是while语句结束了。⽽函数体之后的语句会继续执⾏。
同理,全局变量在⼦进程中进⾏了修改,但是⼦进程的修改没有办法反应到⽗进程中,全局变量只是作为⼀个环境变量传⼊⼦进程,⼦进程修改⾃⼰的环境变量,不会影响到⽗进程。
因此在写shell函数的时候,⽤到管道(cmd &后台进程也⼀样)的时候⼀定要清楚此刻是从什么地⽅返回。
3) echo 返回值
其实在shell中,函数的返回值有⼀个⾮常安全的返回⽅式,即通过输出到标准输出返回。因为⼦进程会继承⽗进程的标准输出,因此,⼦进程的输出也就直接反应到⽗进程。
⽰例4:
#!/bin/sh
function test()
{
echo"arg1 = $1"
if [ $1 = "1" ] ;then
echo"1"
else
echo"0"
fi
}
echo
echo"test 1"
test 1
echo
echo"test 0"
test 0
echo
echo"test 2"
test 2
结果:
test 1
arg1 = 1
1
test 0
arg1 = 0
test 2
arg1 = 2
怎么?有没有搞错,这两个函数⼏乎没什么区别,对,它⼏乎就是return和echo不⼀样,但是有⼀点⼀定要注意,不能向标准输出⼀些不是结果的东西(也就是说,不能随便echo⼀些不需要的信息),⽐如调试信息,这些信息可以重定向到⼀个⽂件中解决,特别要注意的是,脚本中⽤到其它类似grep这样的命令的时候,⼀定要记得1>/dev/null 2>&1来空这些输出信息输出到空设备,避免这些命令的输出。
#! /bin/sh
function test()
{
echo"test here"
return 100
}
DD=`test`
#echo excute over
echo"DD: $DD"
如上shell代码段,执⾏结果是
return: 100
DD: test here
如果把#echo excute over注释去掉,执⾏结果是
excute over
return: 0
DD: test here
也就是说:$?是接收上⼀条函数的执⾏结果,在例⼀中,$?接收test函数的执⾏结果,执⾏结果其实就是其返回值,就是return 传出来的数值(return只能是数字,不能是字符串之类的),如果函数中没有显式调⽤return返回出来状态,那么系统会使⽤函数中最后⼀条shell指令的执⾏结果作为返回值,如
果函数test()最后⼀条指令调⽤其他函数,如:test1(),那么test的返回值就是test1的返回值。
DD是作为⼀个变量接收函数的标准输出,⽐如echo产⽣出来的信息,不包括报错之类的信息,如上如果函数test中调⽤test1,那么test和test1中的标准输出都会赋值给变量DD.
注意:DD=`test` , ` `符号不是单引号‘’,⽽是ESC下⾯的那个符号,该句话的意思是执⾏函数test结果赋值给DD,如果是单引号的话这句话是把字符串“test”赋值给变量DD,注意,这句话的执⾏结果不是赋值是否成功,⽽是函数的执⾏状态
总结:所以,可以总结⼀下函数返回值获取的⽅法:
1)⽤变量接收函数返回值,函数⽤echo等标准输出将要返回的东西打印出来。
2)⽤$?来接收函数的执⾏状态,但是$?要紧跟在函数调⽤处的后⾯。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论