2

在我的程序中,我试图从函数返回一个值,返回值是字符串。一切正常(至少在某些部分),如果我在返回值后回显该值,但如果我不返回,它甚至不会调用该函数......考虑下面的代码......

#!/bin/bash

function get_last_name() {
    echo "Get Last Name"
    ipath=$1

    IFS='/'
    set $ipath
    for item
            do
                    last=$item
            done

    echo $last
}

main() {
    path='/var/lib/iscsi/ifaces/iface0'
    current=$(get_last_name "$path")
    echo -n "Current="
    echo $current
}


main

它给了我这样的输出

OUTPUT
     Current=Get Last Name iface0

如果我评论 echo $current,那么我什至没有看到“获取姓氏”,因此得出的结论是,它甚至没有调用该函数。请让我知道我犯了什么错误。但有一点我可以肯定,bash 是我见过的最丑陋的语言......

4

1 回答 1

7

函数在 bash 中没有返回值。当你写

current=$(get_last_name "$path")

您没有将返回值分配给current. 您正在捕获get_last_name(使用命令编写echo)的标准输出并将其分配给current. 这就是您看不到“获取姓氏”的原因;该文本不会到达终端,而是存储在current.


详细解释

让我们get_last_name先来看看(稍作修改以简化解释):

function get_last_name () {
    ipath=$1

    local IFS='/'
    set $ipath
    for item
    do
        last=$item
    done

    echo "Get Last Name"
    echo $last
}

我之前添加了local命令,IFS以便将更改限制在 的正文中get_last_name,我将第一个echo移到末尾以强调两个echo语句之间的相似性。当get_last_name被调用时,它处理它的单个参数(一个包含文件路径的字符串),然后回显两个字符串:“获取姓氏”和文件路径的最后一个组成部分。如果您要从命令行运行执行此函数,它会显示如下:

$ get_last_name /foo/bar/baz
Get Last Name
baz

该函数的退出代码将是最后执行的命令的退出代码,在这种情况下为echo $last. 只要写入成功(几乎肯定会),这将是 0。

现在,我们看一下函数main,它调用get_last_name

main() {
    path='/var/lib/iscsi/ifaces/iface0'
    current=$(get_last_name "$path")
    echo -n "Current="
    echo $current
}

就像 with 一样get_last_namemain不会有返回值;它将产生一个退出代码,即echo $current. 该函数首先get_last_name在命令替换 ( $(...)) 内部调用,它将捕获所有标准输出get_last_name并将其视为字符串。

题外话

请注意以下内容之间的区别:

current=$(get_last_name "$path")

将 的值设置current为 的累积标准输出get_last_name。(除此之外,输出中的换行符被替换为空格,但如何处理空格的完整解释是另一天的话题)。这与返回值无关;请记住,退出代码(壁橱bash必须“返回值”)是一个整数。

current=get_last_name "$path"

甚至不会打电话get_last_name。它将“$path”解释为命令的名称并尝试执行它。该命令将current在其环境中具有字符串值“get_last_name”的变量。

关键是,get_last_name不会“返回”您可以分配给变量的任何内容。它有一个退出代码,它可以写入标准输出。该$(...)构造允许您将该输出捕获为一个字符串,然后您可以(除其他外)将其分配给一个变量。

回到main

一旦 的值current被设置为由 生成的输出get_last_name,我们执行最后两条echo语句再次写入标准输出。第一个写入 "Current=" 而没有换行符,因此下一个echo语句在与第一个语句相同的行上生成文本。第二个只是呼应 的值current

当您注释掉 的最后一个echomain,您并没有停止get_last_name被执行(它已经被执行了)。相反,您只是没有打印current变量的内容,输出的get_last_name位置而不是终端上。

于 2012-07-13T19:10:11.523 回答