除非我回显返回值,否则不会调用Bash函数

时间:2012-07-13 18:56:37

标签: bash shell

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

#!/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,那么我甚至没有看到“Get Last Name”,这使得得出结论,它甚至没有调用函数。请让我知道我犯了什么错误。但有一件事我肯定,bash是我见过的最丑陋的语言.......

1 个答案:

答案 0 :(得分:5)

函数在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
}

get_last_name一样,main也没有返回值;它将生成一个退出代码,它是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的价值。

当您注释掉echo的最后一个main时,您没有停止执行get_last_name(它已被执行)。相反,您只是没有打印current变量的内容,其中放置了get_last_name的输出而不是终端。