当递归调用bash函数时,它是否创建自己的新实例?



我有一个函数,它对自己进行了多次调用,但它似乎接近其终止值。例如

function multi () {
    a = $1
    b = $2
    c = a + b
    if [[ a > 2 ]]
    then
        let "$a = $a -1"
        multi $a $b
    fi
}

调用multi时,新的子函数使用旧的变量

隐式创建的变量对于当前shell是全局的-因此,函数的每次递归都将覆盖相同的全局变量。

local声明变量,使它们对函数(调用)是局部的。

也就是说,你的函数存在多个问题(如果你真的使用bash,你的函数根本不应该执行):
  • 变量赋值不能在=周围有空格(除非在((...))内部)
  • 算术表达式如c = a + b必须在((...))内执行
  • >的数值比较必须在((...))内执行(或者,将[[ ... ]]-gt一起使用,但是您的变量引用必须以$为前缀)
  • 正如@Florin Stingaciu在他的回答中指出的,你不能在传递给let的赋值的左边使用$前缀——不过,最好在这里也使用((...)),因为它简化了事情:let "a = $a -1"简单地变成了(( --a ))

通常,将代码粘贴到http://shellcheck.net会暴露这些问题。

下面是一个可用的版本:

function multi() {
    local a b c  # declare variables as _local_
    a=$1
    b=$2
    (( c = a + b ))
    if (( a > 2 ))
    then
      (( --a ))
      multi $a $b
    fi
}

这是因为你有几个错误。下面是工作版本:

function multi () {
  a=$1
  b=$2
  c=a+b
  if [[ $a -gt 2 ]]
  then
    let "a = $a -1"
    multi $a $b
  fi
}

if [[ a > 2 ]]

当它应该是:

if [[ $a -gt 2 ]]

let语句也是错误的。应该是:

let "a = $a -1"

最新更新