简体   繁体   中英

Linux bash script, recursion for adding numbers

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM