You are not logged in.

#1 2010-04-04 21:00:18

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Small recursive function, strange bash result...

Today I was speaking with a friend about bash scripts and while speaking I wrote this:

#!/bin/bash

function div {
    diff=$(($2 - $1))
    if test $diff -le 5 ;then
        echo $1 $2
    else
        half=$(( ($1 + $2) / 2))
        div $1 $half
        div $half $2
    fi
}

div 1 30

Just to show that recursion works. Unfortunately, the output proved me wrong:

1 4
4 8
4 9
9 12
12 15
12 16
16 21
16 19
19 23
19 24
24 27
27 30

Confused I wrote this C program:

void div(int b, int e) {
    if ((e-b) <= 5) {
        printf("%d %d\n", b, e);
    }
    else {
        int half = (b + e) / 2;
        div(b, half);
        div(half, e);
    }
}

int main() {
    div(1,30);
}

and the output was the expected:

1 4
4 8
8 11
11 15
15 18
18 22
22 26
26 30

Obviously I ignore something about bash... can anyone help me understand the outputs difference?

Offline

#2 2010-04-04 21:39:39

Procyon
Member
Registered: 2008-05-07
Posts: 1,819

Re: Small recursive function, strange bash result...

Bash functions retain variables. Surround the two recursive div call in ( ) to make a subshell. I tried it and the output was then the same as C's.

Offline

#3 2010-04-04 21:58:40

ezzetabi
Member
Registered: 2006-08-27
Posts: 947

Re: Small recursive function, strange bash result...

Thanks a lot! New lesson today: use ( ) in recursive calls in bash!

Offline

#4 2010-04-05 00:07:09

Xyne
Administrator/PM
Registered: 2008-08-03
Posts: 6,965
Website

Re: Small recursive function, strange bash result...

ezzetabi wrote:

Thanks a lot! New lesson today: use ( ) in recursive calls in bash!

tomorrow's lesson: don't use recursive calls in bash
the day after tomorrow's lesson: don't use bash

tongue


My Arch Linux StuffForum EtiquetteCommunity Ethos - Arch is not for everyone

Offline

#5 2010-04-05 04:29:00

tavianator
Member
From: Waterloo, ON, Canada
Registered: 2007-08-21
Posts: 859
Website

Re: Small recursive function, strange bash result...

Xyne wrote:
ezzetabi wrote:

Thanks a lot! New lesson today: use ( ) in recursive calls in bash!

tomorrow's lesson: don't use recursive calls in bash
the day after tomorrow's lesson: don't use bash

tongue

+1.  Using a subshell will generally actually create a new process, which is about the least efficient stack implementation I can think of.

Offline

#6 2010-04-05 17:37:17

Profjim
Member
From: NYC
Registered: 2008-03-24
Posts: 658

Re: Small recursive function, strange bash result...

It might also work (without needing a subshell) if you precede the half=... with a "local".

Offline

#7 2010-04-06 20:13:24

skanky
Member
From: WAIS
Registered: 2009-10-23
Posts: 1,847

Re: Small recursive function, strange bash result...

Profjim wrote:

It might also work (without needing a subshell) if you precede the half=... with a "local".

Yes, it should do. I have a recursive bash function that works as expected using "local".

I tend to use local unless I have a reason not to, so I rarely have to worry about variable naming if I use a function in another function or script.


"...one cannot be angry when one looks at a penguin."  - John Ruskin
"Life in general is a bit shit, and so too is the internet. And that's all there is." - scepticisle

Offline

#8 2010-04-06 20:32:31

Peasantoid
Member
Registered: 2009-04-26
Posts: 928
Website

Re: Small recursive function, strange bash result...

Profjim wrote:

It might also work (without needing a subshell) if you precede the half=... with a "local".

Hmm, I actually tried that earlier (with OP's function) and it didn't work. Seems to me that 'local' *only* affects scope, not lifetime. Kind of like a C variable with the 'static' qualifier.

// Wait, no. Disregard that. I prefixed $diff, not $half. *smacks self*

Last edited by Peasantoid (2010-04-06 20:34:43)

Offline

Board footer

Powered by FluxBB