0

I can't understand why userType is not changing.

I know for certain it's successfully reaching determineType, but it isn't changing the value to "bbb" when I try to print out userType later.

userType="aaa"

function determineType {
    userType="bbb"
}

function checkUser {
    cat users.csv | \
    while read userLine; do
        if [[ $userLine =~ .*$user.* ]]
            then
            determineType
            echo "1"
        fi
    done
    echo "0"
}
Geesh_SO
  • 2,156
  • 5
  • 31
  • 58
  • It would be nice if you could rephrase the question in a way that would make it less localized and more useful for other people. – Lev Levitsky Nov 26 '12 at 11:00
  • 2
    Your `while` loop is a completely new subshell http://stackoverflow.com/questions/124167/bash-variable-scope – soulseekah Nov 26 '12 at 11:01
  • Have a look at "global vs. local" bash variables. http://www.thegeekstuff.com/2010/05/bash-variables/ – cb0 Nov 26 '12 at 13:42

2 Answers2

2

You are using a pipe, which launch the while .. do in a subshell. Changing the value of a variable in a subshell won't affect the original variable

You should replace the:

function checkUser {
    cat users.csv | \
    while read userLine; do
        if [[ $userLine =~ .*$user.* ]]
            then
            determineType
            echo "1"
        fi
    done
    echo "0"
}

with

function checkUser {
    while read userLine; do
        if [[ $userLine =~ .*$user.* ]]
            then
            determineType
            echo "1"
        fi
    done < users.csv
    echo "0"
}

(This also get rid of a Useless Use Of Cat)

Olivier Dulac
  • 3,695
  • 16
  • 31
2

As soulseekah said in a comment, your while loop is executed in a subshell. Instead, do (and, as a benefit, you get rid of the useless use of cat):

userType="aaa"

determineType() {
    userType="bbb"
}

checkUser() {
    while read userLine; do
        if [[ $userLine = *$user* ]]; then
            determineType
            return 1
        fi
    done < users.csv
    return 0
}

Note. I also changed a few things:

  • got rid of the useless regexp since the same can be achieved with globbing,
  • used more common ways of defining functions in bash,
  • used return instead of echo for returning values: you'd run into the same problem again with an echo: you'd probably use your function checkUser in another subshell to obtain the value returned by the echo.
gniourf_gniourf
  • 44,650
  • 9
  • 93
  • 104