Addition in bash
David N. Lombard
dnl at speakeasy.net
Wed Oct 14 10:14:01 UTC 2009
Ray Parrish wrote:
> Hello,
>
> I have the following script fragment
>
> Seconds=0;
> while [ "$Seconds" -lt "60" ]
> do
> sleep 5;
> Seconds=$Seconds+5;
> padsp espeak "$Seconds"
> done
>
> For some reason Seconds becomes "0+5" instead of the integer value 5
> which is what I am attempting to get it to be.
Yes, you're doing a string concatenation there, "+5" is being
concatenated to "0" to get "0+5". Exactly what you asked for. ;)
> Does anyone know how to do integer math in bash?
For *bash* and not sh, I would rewrite the above as:
Seconds=5
while [[ $Seconds < 60 ]]
do
sleep 5
(( Seconds += 5 ))
padsp espeak $Seconds
done
Note these changes:
1) I used the *bash* double bracket conditional form. This offers
better testing *and* it changes how the strings are interpreted, for
example, you don't have to quote null strings or protect special
characters since you're not building an executable string.
2) The double parentheses arithmetic expression. This doesn't require
the $ to indicate a variable and permits C-style operators.
3) You don't have to quote every occurrence of every string. You only
need to be mindful of spaces and special characters. So, I didn't quote
the $Seconds on the padsp line.
4) You only need the semicolon to break a single physical line into
multiple statements. You don't have that here. An example that would
require the semicolon is
while [[ $Seconds < 60 ]] ; do
BTW, you may have meant to initialize $Seconds at 0. The current form
will result in 10, 15, 20, 25, ... 60.
Also, you could do this without arithmetic using
for Seconds in $(seq 5 5 60) ; do
sleep $Seconds
padsp espeak $Seconds
done
Note that seq puts the increment before the last value, unlike most for
constructs.
If you really did want sh, Bourne shell, you would do the arithmetic as
Seconds=`expr $Seconds + 5`
--
David N. Lombard
More information about the ubuntu-users
mailing list