LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   BASH shell question, variable sustitution $1... command line args (https://www.linuxquestions.org/questions/linux-newbie-8/bash-shell-question-variable-sustitution-%241-command-line-args-875750/)

mnemry 04-18-2011 07:22 PM

BASH shell question, variable sustitution $1... command line args
 
Hi everyone,

I have a need to sum command line arguments in either a while or until loop. (easy to do in a for loop, but can't use one). Given the command line;

'script.sh 10 20 30 40'

I must sum the values of $1 thru $4 but having trouble getting the substitution right, I've tried

TOTAL=$(($TOTAL+$\$COUNTER))
TOTAL=$(($TOTAL+${$COUNTER}))

trying to expand $\$COUNTER to, say $1, and add the value to TOTAL but can't seem to get it right. Any advise is welcome

chrism01 04-18-2011 07:41 PM

Show us your code so far. As part of a general soln, lookup the 'shift' cmd in bash...
http://linux.die.net/abs-guide/othertypesv.html

mnemry 04-18-2011 08:40 PM

#!/bin/bash

# sum_until.sh
# Author: Mark Emry
# Created: 4/17/2011
# Modified: 4/17/2011,


# Purpose: until loop exercise
# Description: sums numbers in a until loop


clear
echo
echo

NUMS="$@"
TOTAL=0
TNUMS="$#"
COUNT=1

until [ $COUNT -gt $TNUMS ]
do
TOTAL=$(($TOTAL+${$COUNT}))
COUNT=$(($COUNT+1))
done

echo "$NUMS = $TOTAL"

#end

BTW, thanks for the link. I modified the script to use the shift command like so;

until [ $COUNT -gt $TNUMS ]
do
TOTAL=$(($TOTAL+$1))
shift
COUNT=$(($COUNT+1))
done

and that works just fine. Still wondering about my original methodology, is it even possible?

Telengard 04-18-2011 09:45 PM

Quote:

Originally Posted by mnemry (Post 4328757)
TOTAL=$(($TOTAL+${$COUNT}))
COUNT=$(($COUNT+1))

Looks like you are trying to use $COUNT as an index to the passed parameters. I don't think it can work that way. Instead try indirect expansion.

Code:

foo$ cat echoparms
#! /bin/bash

c=0
while [[ c -le $# ]]
do
    c=$((c+1))
    echo ${!c}
done
foo$ ./echoparms one two three
one
two
three

foo$

Of course you could always just copy all the arguments into a true Bash array first.

If I were to write a shell script to sum all arguments it would look a little different. I think what you're doing may work okay for you, but it could be simpler.

HTH

Edit
This question reminds me of some of my school assignments. For extra credit, can you tell why my loop runs one more iteration than needed?
;)

grail 04-18-2011 11:52 PM

I have two queries for you:

1. Do you have to change all the standard variables ($#, $@ and so on) to new variable names?

2. You seem to use the arithmetic brackets (()) for some things but not others?

As you have provided your current solution, you may also consider:
Code:

#!/bin/bash

echo -n "$@ = "

until (( $# == 0 ))
do
    (( TOTAL += $1 ))
    shift
done

echo $TOTAL


MTK358 04-19-2011 08:27 AM

You don't put $ in front of variables inside arithmetic expressions.

Telengard 04-19-2011 03:10 PM

Quote:

Originally Posted by MTK358 (Post 4329285)
You don't put $ in front of variables inside arithmetic expressions.

Maybe you don't, but Bash allows it and expressions evaluate just the same.

Code:

foo$ i=1
foo$ echo $(( i ))
1
foo$ echo $(( $i ))
1
foo$ if (( $i == 1 )) ; then echo "true" ; else echo "false" ; fi
true
foo$ i=0
foo$ if (( $i == 1 )) ; then echo "true" ; else echo "false" ; fi
false
foo$

Quote:

Originally Posted by 6.5 Shell Arithmetic - Bash Reference Manual
Shell variables are allowed as operands; parameter expansion is performed before the expression is evaluated. Within an expression, shell variables may also be referenced by name without using the parameter expansion syntax.

http://www.gnu.org/software/bash/man...ell-Arithmetic

MTK358 04-19-2011 03:35 PM

Quote:

Originally Posted by Telengard (Post 4329775)
Maybe you don't, but Bash allows it and expressions evaluate just the same.[/code]

OK, I thought it wouldn't work if you used the "$" syntax.

I also didn't know that for if statements, you can omit the "$" from in front of "((" and it will evaluate if 1 is returned. I always did it like this:

Code:

if [ $(( a == b )) '!=' 0 ]
...


Telengard 04-19-2011 04:40 PM

Quote:

Originally Posted by MTK358 (Post 4329808)
I also didn't know that for if statements, you can omit the "$" from in front of "((" and it will evaluate if 1 is returned.

Quote:

Originally Posted by 3.2.4.2 Conditional Constructs - Bash Reference Manual
((...))

(( expression ))

The arithmetic expression is evaluated according to the rules described below (see Shell Arithmetic). If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1. This is exactly equivalent to

let "expression"

http://www.gnu.org/software/bash/man...nal-Constructs
  • (( EXPRESSION )) yields a status based on the result of EXPRESSION.
  • $(( EXPRESSION )) expands to a value from the result of EXPRESSION.

I think I explained that right :p
To be fair, Bash is quite sophisticated and has many non-obvious constructs.


All times are GMT -5. The time now is 04:44 AM.