Shell 的函数就是一个大坑,坑的人不要不要的。
不同于目前流行的Java
等语法,shell 的方法形参在声明的时候不需要显示声明的,调用的时候也是直接写在方法名后面,通过空格分隔。
比如定义一个两数求和,传统的写法可能类似如下所示:
sum(a,b){
return a+b
}
res=sum(1,2)
echo res
但是shell
的写法是:
sum(){
return $(($1+$2))
}
sum 1 2
echo "$?"
shell 的方法有如下一些奇怪的地方
$1~$n
进行获取((expr))
包起来$((expr))
获取到运算后的值$?
表示的含义是:
exit
的退出状态,通过 0 表示成功,1 表示失败,此处可以参考:参考return
出来的返回值。shell 中函数的返回值只能是数值类型,是的,你没有看错就是数值类型。当你返回字符串的时候,会报错: return: xxx: numeric argument required
。
下面的测试代码,大家可以执行。
a(){
return "ab"
}
b(){
return "123"
}
#调用a,报错:ab: numeric argument required
a
#调用b,成功,但是无任何内容输出
b
以下为江湖传言:shell 的返回值设计的目的不同于其他语言,其表示的是函数的执行结果,0 表示成功,1 表示失败。
那么如何接受函数的返回值了,单函数的返回值是数值类型的时候,有 3 种办法:
其实也是有 3 种方法进行接收
$(expr)
进行标准输出内容的接收a(){
echo 1
}
b=$(a)
echo "$b"
$?
接收上一条指令的返回值a(){
return 1
}
a
echo "$?"
a(){
b=1
}
a
echo "$b"
当返回值是字符的时候,上述的第二种写法就不可以了,需要使用第一种和第三种写法。
a(){
name="ab"
}
# 直接调用全局变量 $name
echo "name:$name"
$(method)
来接收函数中的输出,其中$(expr)
是固定用法,表示接受表达式输出到标准输出的值。a(){
echo "ab"
}
# 执行该操作后的值就是 ab
re=$(a)
echo "name:$re"
假如有一个函数是sum
,有 3 种情况分别对应调用函数时的写法
sum
就行了。return
返回的数值类型的时候,也是直接写,然后通过$?
接收echo
输出的时候,需要通过:$(expr)
进行接收上文已经提到过了,函数的返回值只能是数值。在接收返回值上,也同当前的通用语言不同,比如下面这个做法就无法获取到返回值。
错误写法:
sum(){
return 5
}
b=sum
echo "b:$b"
#输出内容是 b=sum
因为 shell 认为你是在进行赋值操作,将字符串sum
赋值给 b
,正确的做法是通过$?
来获取返回值。
正确的写法是
sum(){
return 5
}
sum
b=$?
echo "b:$b"
#输出内容是 b:5
对于通过echo
输出结果的方法,函数调用的时候,需要通过$((expr))
sum(){
echo 667 #1
return "5"
}
# 通过$(method)调用
b=$(sum)
echo "b:$b"
通过b=$(sum)
获取的是函数sum
的标准输出,说人话就是类似echo
在控制台的输出内容。
案例 1:
sum(){
echo 6
return "5"
}
a=$(sum)
echo "b:$?"
echo "a:$a"
结果就是
b:5
a:6
$?
表示的是最近的return
的值或者exit
的值,很显然就是return
的 5$(expr)
获取的是echo
所以是 6案例 2:
sum(){
echo 6
echo "i love wmm"
echo "i love kotlin"
return "5"
}
a=$(sum)
echo "$a"
#输出结果是
6
i love wmm
i love kotlin
$0-$n
来调用。method [param]
即可。a
,其表示的函数的意义是函数执行过程中的标准输出,如果要获取返回值需要通过$?
。$(method)
进行标准输出的接收,此时函数中的标准输出就不会打印到控制台,而是赋值到变量中了
$?
表示的含义其实是上一次命令的返回值或者退出值,所以假如要获取返回值,建议在函数执行的下一行使用该变量,避免中间执行其他指令,将返回值(退出值)覆盖。
re=$(method)
该调用会将函数中本身的控制台输出吃掉,然后复制给参数re
。