I want to figure it out how recursion works in bash scripting.
I want to insert number as a parameter:
sh script.sh 4
And result would be (1+2+3+4)= 10
This is what I wrote and in my head works just fine, but can't make it work.
n=$1
j=1
result=0
recursion(){
result=`expr $result + $j`
j=`expr $j + 1`
if [ "$n" -gt 0 ]; then
recursion #is this how you do recursion?
n=`expr $n - 1
else
echo $result
fi
}
recursion
I think I imagined right but probably I am wrong.
Don't use global variables:
#!/bin/bash
add_recursively () {
local n=$1
local sum=${2:-0}
if (( n == 0 )); then
echo $sum
return
fi
$FUNCNAME $((n - 1)) $((sum + n))
}
# input validation
if ! [[ $1 =~ ^[[:digit:]]+$ ]]; then
echo "I need a non-negative integer, not $1"
exit 1
fi
echo $(add_recursively $1)
Notes:
local
declares the named variables to be local to this function ( ref ) sum=${2:-0}
defines the "sum" variable as the 2nd parameter, or 0 if the 2nd parameter is empty or unset ( ref ) $FUNCNAME
name of the currently running function ( ref ). This is the recursive call, passing "n-1" and "sum+n" as the parameters. This can be implemented as a shell function:
rec() { [ "$1" -gt 0 ] && echo $(( $1 + $( rec $(($1-1)) ) )) || echo 0 ; }
Here are sample results showing rec
being defined at the command line and then run for several cases:
$ rec() { [ "$1" -gt 0 ] && echo $(( $1 + $( rec $(($1-1)) ) )) || echo 0 ; }
$ rec 4
10
$ rec 5
15
$ rec 6
21
How it works: The function rec
takes a single integer argument. It first checks if that argument is greater than zero. This is done using test
: [ "$1" -gt 0 ]
. If it is greater than zero, it adds the argument to the result of rec $(($1-1))
. If the argument is zero, it just returns (echoes) zero.
Implemented using if/then/else: Some may find it more clear if the &&
/ ||
logic is replaced with an if
statement:
rec() {
if [ "$1" -gt 0 ]
then
echo $(( $1 + $( rec $(($1-1)) ) ))
else
echo 0
fi
}
You can use this recursive function:
recuradd() {
n=$1
[[ $n -eq 0 ]] && return
(( res += n-- ))
recuradd $n
}
Then call using:
res=0; recuradd 4; echo $res
10
res=0; recuradd 5; echo $res
15
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.