尝试在 Bash 中的函数内调用函数,但 returns 出错

Trying to call a function within a function in Bash but it returns errors

我看过溢出和交换,但我似乎找不到这个问题的答案。我目前正在尝试制作一个 递归斐波那契函数。 但是当我尝试测试它时(使用命令行输入)它一直 return 报错

fork: retry: Resource temporarily unavailable

我发现 post 说它与 shell 资源限制有关,但我觉得这可能不是我的问题,因为我已经看到单独的 post具有递归函数的 s 能够足够好地调用它们的函数。

我已将操作分解成多个部分以查看究竟发生了什么,但我找不到具体问题 - 这可能与我调用函数的方式有关,但我不确定, 要么.

虽然我可以传递我想要的参数。对于我输入的任何数字,它只会打印相同的错误。如果我输入 5,它会回显 fork 错误五次。它 returns,但不 return 值...

为了规范,我目前使用 Bash 版本 4.4.20(1)

function fib_r
{
    int=

    for ((i=1; i<=int; i++))
    do

    f1=$(fib_r $((int-1)))
    f2=$(fib_r $((int-2)))
    fibo=$((f1+f2))

    done
}

我想要实现的是,当您在命令行中输入一个数字时,它会计算该数字,但是它会显示每一步的计算数字,而不是 return 从开始到结束的最终值:

示例输出:

1          1
2          1
3          2
4          3
5          5
6          8
7          13
8          21
9          34
10         55

Shellcheck-clean 代码修复了问题中代码的一些问题:

function fib_r
{
    local -r n=

    if (( n == 0 )); then
        echo 0
    elif (( n == 1 )); then
        echo 1
    else
        local -r f1=$(fib_r "$((n-1))")
        local -r f2=$(fib_r "$((n-2))")
        echo "$((f1+f2))"
    fi

    return 0
}
  • 它为 base cases(0 和 1)添加代码以停止递归。原始代码没有基本情况,因此递归一直持续到资源耗尽。
  • 函数 echo 提供了结果,因此它可供调用者使用。 Command substitution ($(command)) 通常只有在 command 将其结果打印到标准输出时才有用。
  • 循环已被删除,因为这应该是一个递归函数(并且循环没有用)。
  • local 用于使变量成为函数的局部变量,这样它们就不会与使用该函数的程序中其他地方使用的变量发生冲突。使用 -r(只读)选项是因为变量永远不需要在函数内更改,并且可以防止它们被其他函数意外更改。
  • 变量名 int 已更改为 n 因为对于像这样的函数来说这是更常规的(并且 int 对于了解 C 或相关编程语言的人来说似乎真的很奇怪).

请注意,此功能非常慢。这部分是因为它使用命令替换(每次都运行昂贵的 sub-process)到 return 结果,但主要是因为这种特定的递归算法效率非常低(指数复杂度,参见 Computational complexity of Fibonacci Sequence) . 很多更快的递归实现是可能的。

问题已更新为请求打印所有斐波那契数直到给定数的函数。这是一个递归函数:

function fib_r
{
    local -r n=
    local -r depth=${2-1}
    local -r f1=${3-1}
    local -r f2=${4-0}

    if (( depth <= n )); then
        printf '%2d  %d\n' "$depth" "$f1"
        fib_r "$n" "$((depth+1))" "$((f1+f2))" "$f1"
    fi

    return 0
}

这使用了更高效的算法 (O(n)),因此它可以在几分之一秒内计算出所有可以用 64 位整数表示的斐波那契数。 运行 fib_r 92 做到这一点。