LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   bash: resetting of global variable? (https://www.linuxquestions.org/questions/programming-9/bash-resetting-of-global-variable-780594/)

crts 01-07-2010 12:25 PM

bash: resetting of global variable?
 
Hi,

I the following code to search a directory recursively:

Code:

declare -i COUNTER=0

# start recursive search
recurse ()
{
echo counter: $COUNTER
        ls "$2" | while read a
        do
                if [ -d "$2"/"$a" ]
                then
                        if [[ "$a" == "." || "$a" == ".." ]]
                        then
                                continue
                        else
                                recurse "$1" "$2"/"$a"
                        fi
                else
                        let "COUNTER += 1"
                        echo "$2"/"$a" >> "$1" # for debugging only: put them into file to verify if all files are found
                fi
        done
}

recurse $LOGPATH $SEARCHDIR

Now the code works fine but COUNTER is not being incremented. The output I get is:
Code:

counter: 0
counter: 0
counter: 0
counter: 0

It appears that COUNTER is being treated like a local variable. Until now I thought local variables have to be defined explicitly as local. So I am a bit confused now.

PTrenholme 01-07-2010 12:54 PM

Try COUNTER=$(($COUNTER + 1)).

Wouldn't it easier just to do a ls -r $1?

crts 01-07-2010 01:05 PM

Quote:

Originally Posted by PTrenholme (Post 3817811)
Try COUNTER=$(($COUNTER + 1)).

Hi,

I already tried COUNTER=$(($COUNTER + 1)). Does not work.

Quote:

Wouldn't it easier just to do a ls -r $1?
Did you mean ls -R $2?

Yes, that would be definetly easier. But I am still new to bash and the main purpose for me at this point is educational value rather than efficiency.
Besides, it is still interesting to find out where the bug is.

tuxdev 01-07-2010 01:18 PM

This sort of thing is what "find" is for
http://mywiki.wooledge.org/UsingFind

crts 01-07-2010 01:25 PM

Quote:

Originally Posted by tuxdev (Post 3817839)
This sort of thing is what "find" is for
http://mywiki.wooledge.org/UsingFind

As I already said, there might be better ways to do and I could work around the problem. But I still like to know why COUNTER is being reset to zero every time the function is reentered. It is being incremented by 'let' but it seems that this is not persistent.

tuxdev 01-07-2010 01:36 PM

http://mywiki.wooledge.org/BashFAQ/024
http://mywiki.wooledge.org/ParsingLs

Doing it the right way is not "working around the problem"

crts 01-07-2010 02:26 PM

Quote:

Originally Posted by tuxdev (Post 3817854)
http://mywiki.wooledge.org/BashFAQ/024
http://mywiki.wooledge.org/ParsingLs

Doing it the right way is not "working around the problem"

Hi tuxdev,

the links were really helpful. I used a recursive function and not a recursive call to the same script to avoid the subshell problem. But there it was again.

So this how I do it now:

Code:

find $SEARCHDIR ! -type d >> $LOGPATH
COUNTER=`wc -l $LOGPATH | sed -e 's% .*%%g'`


konsolebox 01-07-2010 07:40 PM

There's a way to make it not run in a subshell environment but it's not a good idea since it will require to spawn multiple processes at runtime. There could also be a limit in the number of file descriptors that can be used.

Code:

declare -i COUNTER=0

# start recursive search
recurse ()
{
echo counter: $COUNTER
        {
                while read a
                do
                        if [ -d "$2"/"$a" ]
                        then
                                if [[ "$a" == "." || "$a" == ".." ]]
                                then
                                        continue
                                else
                                        recurse "$1" "$2"/"$a"
                                fi
                        else
                                let "COUNTER += 1"
                                echo "$2"/"$a" >> "$1" # for debugging only: put them into file to verify if all files are found
                        fi
                done
        } < <(exec ls "$2")
}

recurse $LOGPATH $SEARCHDIR



All times are GMT -5. The time now is 12:53 PM.