4

I recently started learning to code Shell Script and one thing that confuses me is the order of assignment of parameters.

This is the code I have confusion with

#!/bin/bash
Expression() 
{
    local num3=$1
    local num4=$2
    local num5=$3
    local sum=$(((num3-num4)+num5))
echo $sum
}
num1=5
num2=3
num3=7
sum=$(Expression num1 num2 num3)
echo "The result is $sum"

Instead of getting the output as

The result is 9

Since 5-3+7=9

I'm getting it as

The result is 7

Could anyone explain this please?

3 Answers 3

4

The problem is with the expression

sum=$(Expression num1 num2 num3)

where you are passing literal values of num1, num2 and num3 as strings. In the example you have those variables are not passed as placeholders for the values defined, but as raw strings.

You need to pass them as actual placeholders containing those values, by putting a $ before the variable name

sum=$(Expression "$num1" "$num2" "$num3")

I guess the decision you've incorrectly made is, the arithmetic operator $((..)) construct in bash allows you to access variables without the $ prefix made. But for command substitution syntax $(..) requires the variable names to be prefixed with $, else only the literal value gets passed as you've seen here.

As for the value 7, it should be obvious that num3 is defined both global and local inside the function. So the it holds the value 5, so the operation 5-3+5 is performed over 5-3+7 which you expected.

Sign up to request clarification or add additional context in comments.

Comments

3

Proper code:

#!/bin/bash
Expression() 
{
    local num4=$1
    local num5=$2
    local num6=$3
    local sum=$((((num4-num5))+num6))
echo $sum
}
num1=5
num2=3
num3=7
sum=$(Expression num1 num2 num3)
echo "The result is $sum"

Output:

./script.sh
The result is 9

Why your code is not working? When you run your code with bash -x option you will see the difference:

$ bash -x ./script.sh
+ num1=5
+ num2=3
+ num3=7
++ Expression num1 num2 num3
++ local num3=num1
++ local num4=num2
++ local num5=num3
++ local sum=7
++ echo 7
+ sum=7
+ echo 'The result is 7'
The result is 7

num3 is declared as both local and global variable. Since the function is using local one the value 5 is used instead of 7 as you expected.

Comments

0

You have to place a $ in front of the variables:

sum=$(Expression $num1 $num2 $num3)

What happens here is that you pass the names of the variables, not the values. Let's look at a simplified version of your program

#!/bin/bash                                                                                                                                                                                                                                                                     
Expression()
{
    local num5=$1
    echo $((num5))
}
num3=7
echo "The result is $(Expression num3)"

You pass the text num3, not the value 7. The $(()) operator tries to evaluate numbers. num5 is not a number, but it is a variable. So it is replaced with the value, num3. num3 is not a number, so it is replaced with the value, 7.

You can nest this, output is 5.

#!/bin/bash                                                                                                                                                                                                                                                                     
num1=num2
num2=num3
num3=num4
num4=5
echo $((num1))

You can also try this:

#!/bin/bash                                                                                                                                                                                                                                                                     
num1=num2
num2=num3
num3=num4
num4=num1
echo $((num1))

Result is

line 6: num4: expression recursion level exceeded (error token is "num4")

So evaluation is indeed recursive until a number is reached, or a limit.

Comments

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.