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

notice 也可以使用shift命令来处理传递给函数的参数(请参考例子 33-18. 但是,传递给脚本的命令行参数怎么办?在函数内部,可以看见这些命令行参数么?好,现在让我们弄清楚这个困惑。

例子 34-3. 函数以及传递给脚本的命令行参数。

和其它的编程语言相比,shell脚本一般只会传值给函数。如果把变量名(事实上就是指针)作为参数传递给函数的话,那将被解释为字面含义,也就是被看做字符串。 函数只会以字面含义来解释函数参数。

变量的间接引用(请参考例子 37-2)提供了一种笨拙的机制,来将变量指针传递给函数。

例子 24-4. 将一个间接引用传递给函数

接下来的一个逻辑问题就是,将参数传递给函数之后,参数能否被解除引用。

例子 24-5. 对一个传递给函数的参数进行解除引用的操作

例子 24-6. 再来一次,对一个传递给函数的参数进行解除引用的操作

退出与返回码

退出状态码

函数返回一个值,被称为退出状态码。这和一条命令返回的退出状态码类似。退出状态码可以由return 命令明确指定,也可以由函数中最后一条命令的退出状态码来指定(如果成功,则返回0,否则返回非0值)。可以在脚本中使用$?来引用退出状态码。 因为有了这种机制,所以脚本函数也可以像C函数一样有“返回值”。

return

终止一个函数。一个return命令1 可选的允许带一个整形参数,这个整形参数将作为函数的“退出状态码”返回给调用这个函数的脚本,并且这个退出状态码也被赋值给变量$?.

例子 24-7. 取两个数中的最大值

info 为了让函数可以返回字符串或者是数组,可以使用一个在函数外可见的专用全局变量。

例子 24-8. 将阿拉伯数字转化为罗马数字

也可以参见例子 11-29

notice 函数所能返回最大的正整数是255. return命令和退出状态码的概念紧密联系在一起,并且退出状态码的值受此限制。 幸运的是,如果想让函数返回大整数的话,有好多种不同的变通方法 能够应对这个情况。

例子24-9. 测试函数最大的返回值

如果你想获得大整数“返回值”的话,简单的方法就是将“要返回的值”保存到一个全局变量中。

一种更优雅的做法是在函数中使用echo命令将"返回值输出到stdout“,然后用命令替换来捕捉此值。请参考36.7小节关于这种用法的讨论

例子 24-10. 比较两个大整数

这是另一个能够捕捉函数”返回值“的例子。要想搞明白这个例子,需要一些awk的知识。

也请参考例子 A-7例子A-37.

练习:使用目前我们已经学到的知识,来扩展之前的例子 将阿拉伯数字转化为罗马数字,让它能够接受任意大的输入。

重定向 重定向函数的stdin 函数本质上其实就是一个代码块,这就意味着它的stdin可以被重定向(比如例子3-1)。

例子 24-11. 从username中取得用户的真名

还有一个办法,或许能够更好的理解重定向函数的stdin。 它在函数内添加了一对大括号,并且将重定向stdin的行为放在这对添加的大括号上。

extra Emmanuel Rouat的 sample bash 文件包含了一些很有指导性意义的函数例子。

最后更新于

这有帮助吗?