what is the sneaky bug in between val=$a and var=`expr $a+0`?

what is the sneaky bug in between val=$a and var=`expr $a+0`?

Post by Joh » Tue, 05 Nov 2002 01:58:27



I got mad by a command in the following script, hope any one can point it out.
the script is to pick out the last number matched and calculate the sums.

there are two input-data-file

f1:
a       2
b       3
c       5

f2
a       5
c       3
c       0
b       4

the script:
#!/bin/sh
output=""
sum=0
for i in  f1 f2
do
        lastvalue=0
        if [ -s $i ]  
        then
                exec < $i
                while read word value
                do
                if [ "a" = "$word" ]
                then
****                    lastvalue=$value #sneaky bug in command
                fi
                done
        fi
        sum=`expr $sum + $lastvalue : '\([0-9]*\)'`
        output="$output""$lastvalue""\t"
done

echo "$output"SUM:"      ""$sum"

Qustion
something sneaky occured in line ***, above script generated output:
          SUM:    7

but if replace line *** with lastvalue=`expr 0 + $value : '\([0-9]*\)'`
it turned out as what expected as :
2    5    SUM:    7

Actuall var=$value is equivalent to var=`expr $value + 0`

Any tips highly appreciated.

John

 
 
 

what is the sneaky bug in between val=$a and var=`expr $a+0`?

Post by Chris F.A. Johnso » Tue, 05 Nov 2002 07:05:36



> I got mad by a command in the following script, hope any one can point it out.
> the script is to pick out the last number matched and calculate the sums.

> there are two input-data-file

> f1:
> a  2
> b  3
> c  5

> f2
> a  5
> c  3
> c  0
> b  4

> the script:
> #!/bin/sh
> output=""
> sum=0
> for i in  f1 f2
> do
>    lastvalue=0
>    if [ -s $i ]  

   No need; if the file is empty, the while loop itself accomplishes
   the same thing.

Quote:>    then
>            exec < $i
>            while read word value
>            do
>            if [ "a" = "$word" ]
>            then
> ****                       lastvalue=$value #sneaky bug in command
>            fi
>            done
>    fi
>    sum=`expr $sum + $lastvalue : '\([0-9]*\)'`

    All ": '\([0-9]*\)'`" is doing is removing any trailing
    non-numeric characters from $lastvalue.

Quote:>    output="$output""$lastvalue""\t"

    You don't need all those quotation marks:

        output="$output$lastvalue\t"

Quote:> done

> echo "$output"SUM:" ""$sum"

        echo "${output}SUM:        $sum"

Quote:> Qustion
> something sneaky occured in line ***, above script generated output:
>           SUM:    7

> but if replace line *** with lastvalue=`expr 0 + $value : '\([0-9]*\)'`
> it turned out as what expected as :
> 2    5    SUM:    7

> Actuall var=$value is equivalent to var=`expr $value + 0`

> Any tips highly appreciated.

     I get the expected result whichever version I use.

     What system and what version of sh are you using?

--
    Chris F.A. Johnson                        http://cfaj.freeshell.org
    ===================================================================
    My code (if any) in this post is copyright 2002, Chris F.A. Johnson
    and may be copied under the terms of the GNU General Public License

 
 
 

what is the sneaky bug in between val=$a and var=`expr $a+0`?

Post by Joh » Wed, 06 Nov 2002 00:05:55


I'm remote-login from window 2000 to the server
SunOs red 5.8 generic_108528-16 sun4u sparc SUNW,Ultra-Enterprise,
cpu/SUNW,UltraSPARC II
which is for a University,www.yorku.ca/www.cs.yorku.ca

Two issues that even the adminstrator couldn't tell the reason why
that stranger on that srcipt.

1.if didnt' explicityly $lastvalue : '\([0-9]*\)'`
will cause to expr: non-numeric argument
2. if using
lastvalue=$value instead of lastvalue=`expr 0 + $value : '\([0-9]*\)'`
will cause the output
"     SUM:   7" instead of "2    5    SUM:   7"


Quote:> >       sum=`expr $sum + $lastvalue : '\([0-9]*\)'`

>     All ": '\([0-9]*\)'`" is doing is removing any trailing
>     non-numeric characters from $lastvalue.

>         echo "${output}SUM:   $sum"

> > Qustion
> > something sneaky occured in line ***, above script generated output:
> >           SUM:    7

> > but if replace line *** with lastvalue=`expr 0 + $value : '\([0-9]*\)'`
> > it turned out as what expected as :
> > 2    5    SUM:    7

> > Actuall var=$value is equivalent to var=`expr $value + 0`

> > Any tips highly appreciated.

>      I get the expected result whichever version I use.

>      What system and what version of sh are you using?

 
 
 

what is the sneaky bug in between val=$a and var=`expr $a+0`?

Post by Anand Harihar » Wed, 06 Nov 2002 06:00:57



> > >  sum=`expr $sum + $lastvalue : '\([0-9]*\)'`

> >     All ": '\([0-9]*\)'`" is doing is removing any trailing
> >     non-numeric characters from $lastvalue.

> >         echo "${output}SUM:      $sum"


> I'm remote-login from window 2000 to the server
> SunOs red 5.8 generic_108528-16 sun4u sparc SUNW,Ultra-Enterprise,
> cpu/SUNW,UltraSPARC II
> which is for a University,www.yorku.ca/www.cs.yorku.ca

> Two issues that even the adminstrator couldn't tell the reason why
> that stranger on that srcipt.

> 1.if didnt' explicityly $lastvalue : '\([0-9]*\)'`
> will cause to expr: non-numeric argument
> 2. if using
> lastvalue=$value instead of lastvalue=`expr 0 + $value : '\([0-9]*\)'`
> will cause the output
> "     SUM:   7" instead of "2    5    SUM:   7"

My hunch is this might have to do with the trailing ^M characters
(esp. since you mention working DOS <-> UNIX) in the f1 and f2 files.
Suggestion: try viewing these files in an editor such as vi, or do an
octal dump.

HTH,
- Anand

 
 
 

1. while read VAR VAL; do setenv $VAR $VAL; done

Hi,

I use "source set_envs.csh" and ". set_envs.sh" to let
the users set a longer list of environment variables
at our site. Because I don't want to maintain the same
list in 2 files, I'm trying to rewrite the set_envs.csh
to make it just read the set_envs.sh and replace the
"export VAR=VAL" lines by the "setenv VAR VAL".

While the regex for that is easy:

sed -ne 's/^export[       ]*\([^=][^=]*\)=\(.*\)/setenv \1 \2/p' set_envs.sh

I wonder, how to do the rest? In a Bourne shell
I would probably do something like this:

sed -ne 's/^export[       ]*\([^=][^=]*\)=\(.*\)/\1 \2/p' set_envs.sh | \
while read VAR VAL; do
    setenv $VAR $VAL
done

But how do I do the same trick for csh?
I don't see "read" in the "man csh" and
also wonder if I can pipe some command
output into csh's while/end or foreach/end

Thank you
Alex

PS: And no, I don't want to swap the files and
    let the set_envs.sh read the set_envs.csh.
    I'm interested in the csh solution.

2. search on variable passed to awk /nawk

3. xterm -fn 8x13 -geometry 80x30+0+0 -fg white -bg blue &

4. Good GUI-based fax client?

5. /var/mail on RSM 2000 : RAID5 or 1+0 ?

6. prologue development

7. <expr> | while -> var assignment not remembered in Bourne

8. rdate rule

9. Solaris 10: expr bug

10. sh var -> awk var -> sh var

11. Matrox Mystique ands X.

12. tidy(sys): reduce /var/adm/wtmp or "Am I blind"

13. IPCHAINS - sneaky attempts to find misconfigured firewalls