
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。