JH95
JH95

Reputation: 489

Variable not getting re-assigned in shell script

I am having problems re-assigning the POSTCODE_VALID variable. It does not get reassigned when the if condition is met. I have made sure that the if condition is met and that it should be getting set to true. However it is not. Does anyone know why?

POSTCODE_VALID=false
find codepoint/ | while read i ;
do

    if [[ $i =~ codepoint/$AREACODE ]]
            then
                    #This is the variable that doesn't get re-assigned.
                     POSTCODE_VALID=true
    fi
done

Upvotes: 1

Views: 1201

Answers (3)

Mark Setchell
Mark Setchell

Reputation: 208043

Another (quick and dirty) solution would be to use your own code, but to create a temporary file using "touch" if you find your areacode instead of using a variable - a bit ugly, but workable. That would allow more complicated directory structures to be tested.

Of course, you'd have to remove the temp file before you started:

rm /tmp/AreacodeFound 2> /dev/null

Upvotes: 0

chepner
chepner

Reputation: 532333

The pipeline creates a subshell; the assignment to POSTCODE_VALID is local to that shell, and so does not affect POSTCODE_VALID in the parent.

A simpler solution is to just check if codepoint/$AREACODE exists.

if [[ -f codepoint/$AREACODE ]]; then
    POSTCODE_VALID=true
else
    POSTCODE_VALID=false
fi

If you do need to make a more general match, use a for loop and break as soon as you match:

POSTCODE_VALID=false
for f in "codepoint/$AREACODE"*; do
    if [[ -f $f ]]; then
        POSTCODE_VALID=true
        break
    fi
done

(Essentially, this loop will execute at most once; if there is no match, the glob will be treated literally and, of course, will not be the name of an existing file.)

Upvotes: 6

cdarke
cdarke

Reputation: 44434

The problem is your pipe, which (in bash, not ksh) creates a subshell. An alternative to using a pipe is to use process substitution:

POSTCODE_VALID=false
while read i 
do
    if [[ $i =~ codepoint/$AREACODE ]]
    then
        POSTCODE_VALID=true
        break
    fi
done < <(find codepoint/)

I added the break, because once you set the variable there is no point in setting it again.

Although I do like @chepner's solution to avoid the find and read.

Upvotes: 1

Related Questions