24.1 复杂函数和函数复杂性
函数可以处理传递给它的参数,并且能返回它的退出状态码给脚本,以便后续处理。
function_name $arg1 $arg2函数通过位置来引用传递过来的参数(就好像它们是位置参数),例如,$1, $2,等等。
例子 24-2. 带参数的函数
#!/bin/bash
# 函数和参数
DEFAULT=default # 默认参数值。D
func2 () {
if [ -z "$1" ] # 第一个参数长度是否为零?
then
echo "-Parameter #1 is zero length.-" # 或者没有参数传递进来。
else
echo "-Parameter #1 is \"$1\".-"
fi
variable=${1-$DEFAULT}
echo "variable = $variable" # 这里的参数替换
#+ 表示什么?
# ---------------------------
# 为了区分没有参数的情况
#+ 和只有一个null参数的情况。
if [ "$2" ]
then
echo "-Parameter #2 is \"$2\".-"
fi
return 0
}
echo
echo "Nothing passed."
func2 # 不带参数调用
echo
echo "Zero-length parameter passed."
func2 "" # 使用0长度的参数进行调用
echo
echo "Null parameter passed."
func2 "$uninitialized_param" # 使用未初始化的参数进行调用
echo
echo "One parameter passed."
func2 first # 带一个参数的调用
echo
echo "Two parameters passed."
func2 first second # 带两个参数的调用
echo
echo "\"\" \"second\" passed."
func2 "" second # 第一个调用参数为0长度参数,
echo # 第二个是ASCII码的字符串参数。
exit 0
也可以使用shift命令来处理传递给函数的参数(请参考例子 33-18. 但是,传递给脚本的命令行参数怎么办?在函数内部,可以看见这些命令行参数么?好,现在让我们弄清楚这个困惑。
例子 34-3. 函数以及传递给脚本的命令行参数。
和其它的编程语言相比,shell脚本一般只会传值给函数。如果把变量名(事实上就是指针)作为参数传递给函数的话,那将被解释为字面含义,也就是被看做字符串。 函数只会以字面含义来解释函数参数。
变量的间接引用(请参考例子 37-2)提供了一种笨拙的机制,来将变量指针传递给函数。
例子 24-4. 将一个间接引用传递给函数
接下来的一个逻辑问题就是,将参数传递给函数之后,参数能否被解除引用。
例子 24-5. 对一个传递给函数的参数进行解除引用的操作
例子 24-6. 再来一次,对一个传递给函数的参数进行解除引用的操作
退出与返回码
退出状态码
函数返回一个值,被称为退出状态码。这和一条命令返回的退出状态码类似。退出状态码可以由return 命令明确指定,也可以由函数中最后一条命令的退出状态码来指定(如果成功,则返回0,否则返回非0值)。可以在脚本中使用$?来引用退出状态码。 因为有了这种机制,所以脚本函数也可以像C函数一样有“返回值”。
return
终止一个函数。一个return命令1 可选的允许带一个整形参数,这个整形参数将作为函数的“退出状态码”返回给调用这个函数的脚本,并且这个退出状态码也被赋值给变量$?.
例子 24-7. 取两个数中的最大值
为了让函数可以返回字符串或者是数组,可以使用一个在函数外可见的专用全局变量。
例子 24-8. 将阿拉伯数字转化为罗马数字
也可以参见例子 11-29
函数所能返回最大的正整数是255. return命令和退出状态码的概念紧密联系在一起,并且退出状态码的值受此限制。 幸运的是,如果想让函数返回大整数的话,有好多种不同的变通方法 能够应对这个情况。
例子24-9. 测试函数最大的返回值
如果你想获得大整数“返回值”的话,简单的方法就是将“要返回的值”保存到一个全局变量中。
一种更优雅的做法是在函数中使用echo命令将"返回值输出到stdout“,然后用命令替换来捕捉此值。请参考36.7小节 中关于这种用法的讨论。
例子 24-10. 比较两个大整数
这是另一个能够捕捉函数”返回值“的例子。要想搞明白这个例子,需要一些awk的知识。
练习:使用目前我们已经学到的知识,来扩展之前的例子 将阿拉伯数字转化为罗马数字,让它能够接受任意大的输入。
重定向 重定向函数的stdin 函数本质上其实就是一个代码块,这就意味着它的stdin可以被重定向(比如例子3-1)。
例子 24-11. 从username中取得用户的真名
还有一个办法,或许能够更好的理解重定向函数的stdin。 它在函数内添加了一对大括号,并且将重定向stdin的行为放在这对添加的大括号上。
Emmanuel Rouat的 sample bash 文件包含了一些很有指导性意义的函数例子。
最后更新于
这有帮助吗?