nwna
nwna

Reputation: 3

Bash global variable is empty in a function

I just would like to use calc to calculate two global variables that are initialized higher in the code, but as I set -x for debug, one of these is empty and I don't understand, what's wrong.

At the top of my source.sh I have these declarations:

userValue=""
newSolde="
currentSolde=""

[...]

// check the format of a float number

// subsitute "," to "." for 'userValue' will be given to calc later


chkValue() {

if [[ "$1" == +([0-9])?(?(.|,)*([0-9])) ]] 
then
    userValue=$(echo "$1" |sed 's/,/\./')
    newOp="$newOp $userValue"
    return 0
else
    echo "$1 Montant invalide"
    return 1
fi
}

[...]

Here I call the function chkValue:

getOps(){
[[ "$#" -ne 3 ]] && echo -e "missing args" && exit

currentDate=`date +%a%d/%m/%y`
newOp="$currentDate"

# "newOp" is completed by those 3 functions
(chkOperation "$1" && chkMotif "$2" && chkValue "$3") || exit 1
}

calculateNewSolde() {
    newSolde=$(calc -p -- "$userValue"+"$currentSolde") // ***** here it is ****
}

[...]

Here is the result of set -x when I call source.sh -c "a string" 58,6:

+ chkValue 58,6
+ [[ 58,6 == +([0-9])?(?(.|,)*([0-9])) ]]
++ echo 58,6
++ sed 's/,/\./'
+ userValue=58.6 // <--- init there
+ newOp='ven.20/11/15 CREDIT tou hghj 58.6'
+ return 0
+ getCurrentSoldeFrom /iuser/DATABASE/1000/DB_1000
+ database=/iuser/DATABASE/1000/DB_1000
++ grep '^Solde' /iuser/DATABASE/1000/DB_1000
++ awk '{print $NF}'
+ currentSolde=15.6
+ calculateNewSolde
++ calc -p -- +15.6 // <---- ???
+ newSolde=15.6

I really would like to understand this.

Upvotes: 0

Views: 1254

Answers (1)

Anya Shenanigans
Anya Shenanigans

Reputation: 94869

Your problem arises here:

(chkOperation "$1" && chkMotif "$2" && chkValue "$3") || exit 1

This causes a subshell, and thus the setting of the value doesn't carry back into the parent process. You should rewrite this using {}, which allows grouping without a subshell:

{ chkOperation "$1" && chkMotif "$2" && chkValue "$3"; } || exit 1

It has been noted that standard precedence rules mean that the use of braces was not needed in this case either, so it simplifies to:

chkOperation "$1" && chkMotif "$2" && chkValue "$3" || exit 1

Upvotes: 2

Related Questions