ogs
ogs

Reputation: 1239

Add up parameters in for loop

I've implemented a function which contains a while for loop defined as follows:

func()
{
...
 for i in "$@"; do
     enum="source"
     sourceID=$i
     ret_ID $FILE_NAME $sourceID $enum
     ID=$req_ID
     ((ID+=ID))
 done
 echo $ID
}

The function ret_ID parses a file which contains some variables as

param1=0x00000001
param2=0x00000400
param3=0x000008000
...

No matter how many parameters I pass, echo $ID returns the ID associated with the last parameter and not the sum of all of them. For instance, func param1 param3 returns 32768 and not 32769.

Upvotes: 0

Views: 38

Answers (1)

mklement0
mklement0

Reputation: 437353

Update: Judging by a comment by the OP, it sounds like glenn jackman's recommendation to switch from letting ret_ID() set a global variable in order to return its result to outputting its result to stdout and capturing the result in a command substitution ($(...)) solved the problem.

Assuming that the problem wasn't the simple logic error Glenn points out (((ID+=ID)) should be ((ID+=req_ID )): The exact cause of the original problem is not known, but since both func() and ret_ID() operate on global variables, it's easy to see how one function could interfere with the other, such as if ret_ID() accidentally also sets variable $ID.

Here's a rewrite of the function that shows this change, and also suggests a few other changes to make the function more robust, most notably the use of local variables:

func()
{
 # Declare *local* variables.
 local arg enum sourceID retID 
 # Declare the local result variable *as an integer*
 # Also, better to use variable names that at least start with a *lowercase*
 # letter to avoid conflicts with *environment* variables.
 local -i id=0 
 # ...
 for arg; do  # loop over all args; the `in "$@"` part is optional
   enum="source"
   sourceID=$arg
   # Call helper function and let it return its result via *stdout* captured
   # through a command substitution rather than by setting a global variable.
   # Note the use of double quotes to prevent problems with values with embedded spaces.
   reqID=$(ret_ID "$FILE_NAME" "$sourceID" "$enum")
   # Add the value returned to $id
   # Note that since $id was declared as an integer,
   # use of (( ... )) is optional.
   id+=$reqID
 done
 echo "$id"
}

Upvotes: 1

Related Questions