0

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.

5
  • req_ID is a variable set in ret_ID function and retrieved here Commented Mar 15, 2015 at 13:21
  • 2
    $ID can never be an odd value. You set it's value, then double it. You are not accumulating anything. You only return twice the last value of $req_ID. Did you mean ((ID+=req_ID))? Commented Mar 15, 2015 at 13:25
  • 1
    Also, relying on global ideas is a bad idea. ret_ID should return a value, not just set a global variable. Commented Mar 15, 2015 at 13:28
  • I am agree. I modified the line as ID=$(ret_ID $FILE_NAME $sourceID $enum) and an echo $ID displays the good value. Commented Mar 15, 2015 at 13:37
  • 1
    I solved the problem with these two lines. ID=$(ret_ID $FILE_NAME $sourceID $enum) followed by ((VAR+=ID)). Echo $VAR returned the required value Commented Mar 15, 2015 at 13:45

1 Answer 1

1

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"
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank mklement0 for your advices, I will take them in account !!
@SnP: My pleasure. It looks like you've accepted few, if any, of the questions you've asked over time, so let me offer this standard advice: For the benefit of both answerers and future readers: If an answer solved your problem, please accept it by clicking the large check mark next to it; if you found it helpful, please up-vote it by clicking the up-arrow icon.
@SnP: Thanks for accepting; it would be great if you went through your old questions and also accepted answers there, if appropriate. Aside from showing appreciation, it really helps future readers to know what answer actually solved a problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.