There are two problems here. First, all of your variables are global, which means that when you make a recursive call it overwrites the values of nr
, rez
, rez1
, and rez2
. You can fix this by declaring them as local
:
fib() {
local nr rez rez1 rez2
if [ $1 -eq 1 -o $1 -eq 2 ]; then
return 1
else
let nr=$1-1
fib $nr
rez1=$?
let nr=$1-2
fib $nr
rez2=$?
let rez=$rez1+$rez2
return $rez
fi
}
The second problem is that you're trying to pass a number via the return status of the function. The return status is a 1-byte unsigned integer, which means it can't get bigger than 255 (after which it wraps around to 0. It's really intended to give success/failure results (and maybe some information about what failed), with 0 indicating success and anything else indicating an error. Trying to use it for something else is asking for trouble. You can see the results here (from the local
ized version of the function):
$ fib 11; echo $?
89
$ fib 12; echo $?
144
$ fib 13; echo $?
233
$ fib 14; echo $?
121
The 14th Fibonacci number is 377, but that's over 255 so it came out as 377-256 = 121. To fix this, return the result by echo
ing it to stdout and capture it with $( )
:
fib() {
local nr rez rez1 rez2
if [ $1 -eq 1 -o $1 -eq 2 ]; then
echo 1
else
let nr=$1-1
rez1=$(fib $nr)
let nr=$1-2
rez2=$(fib $nr)
let rez=$rez1+$rez2
echo $rez
fi
}
...this does have a disadvantage, though: it's much slower, because every call to fib
has to run as a subprocess, and creating subprocesses is computationally expensive. (This actually would've solved the global-variable problem, since variables inherit down to subprocesses but not up from them; but it only solves it by accident.)
Take-home lesson: shell scripts aren't the right language for things like this.