递归 bash 函数在下降后会失去 return 的能力吗?

Does a recursive bash function lose its ability to return after descending?

参照this post on exiting a function in bash

递归bash函数在递减后会失去return的能力吗?

我试着做一个简单的示例函数来解释。此函数被赋予一个目录并查找具有目录基本名称的 .foo 文件。如果它不存在,它可能只需要重命名,但需要先找到它。我当然可以重写这个。查找循环是需要 return 的原因。在这种情况下,我只是对 bash 函数的递归性质感到好奇。

given_directory=$"/home/bob"
some_function "$given_directory"

some_function () {
    specific_foo_file=$""/"$(basename "")".foo
    if [ -f "$specific_foo_file" ] ; then
        echo "do file stuff"
    else
        find . -name "*.foo"|while file ; do
            if mv "$file" "$specific_foo_file" ; then
                echo "renamed $file to $specific_foo_file"
                some_function $given_directory
                return 0
            else
                echo "could not rename $file"
                return 1
            fi
        done
        echo "can't find any .foo files, oh well"
    fi
}

到目前为止,如果重命名成功,最后的 echo 总是被调用。

编辑: 对于我使用的环境:

-bash-3.2$ uname -a
SunOS XXXXXXXXXX 5.10 Generic_150400-29 sun4v sparc SUNW,SPARC-Enterprise-T5120

如果您想将错误的退出状态传递出多个级别,则需要明确地将其传递到中间层。即:

some_function "$given_directory" || return
  • 如果some_function成功,函数的执行将继续到下一行。
  • 如果 some_function 失败,函数会立即 returns 并使用与失败相同的退出状态。

就是说,因为您有一个 return 0 作为紧跟在您的函数调用之后的行,您可以简单地将其更改为一个空 return,并具有相同的效果。


此外,您还有一个额外的严重问题,因为您的 while 循环发生在子 shell 中,因此当它 return 时,它只会影响子 shell,而不是调用它的外部 shell。相反,重组您的代码以将逻辑放入主 shell:

while IFS= read -r -d '' file ; do
    if mv -- "$file" "$specific_foo_file" ; then
        echo "renamed $file to $specific_foo_file"
        some_function "$given_directory" || return
    else
        echo "could not rename $file"
        return 1
    fi
done < <(find . -name '*.foo' -print0)

请参阅 BashFAQ #24 了解此问题。