f



Strange Bash behavior

Hi,
   My script is as following:

total=0;
fail=0;
pass=0;

perl -ne 'if ($_ =~ /href=\"(.*\.xml)\"/) { print "$1\n"; }' --
"$testdir"/alltests.xml | while read test; do
    total=$((total+1));
    if [ some condition ]; then
       fail=$((fail+1));
    fi
    if [ some condition ]; then
       pass=$((pass+1));
    fi
done

# Here I print the count result
echo "Total: $total";
echo "Pass: $pass";
echo "Fail:   $fail";

------------------------------------------
But the final result are always
Total: 0
Pass: 0
Fail:  0

Why it produce such strange result? I guess it may be the perl ... |
while pipe make Bash produce strange behavior. Could you please help ?
Thanks!

Regards!
Bo
0
Bo
5/9/2009 6:30:20 AM
comp.unix.shell 15484 articles. 2 followers. Post Follow

7 Replies
1171 Views

Similar Articles

[PageSpeed] 13

Bo Yang wrote:
> Hi,
>    My script is as following:
> 
> total=0;
> fail=0;
> pass=0;
> 
> perl -ne 'if ($_ =~ /href=\"(.*\.xml)\"/) { print "$1\n"; }' --
> "$testdir"/alltests.xml | while read test; do
>     total=$((total+1));
>     if [ some condition ]; then
>        fail=$((fail+1));
>     fi
>     if [ some condition ]; then
>        pass=$((pass+1));
>     fi
> done
> 
> # Here I print the count result
> echo "Total: $total";
> echo "Pass: $pass";
> echo "Fail:   $fail";
> 
> ------------------------------------------
> But the final result are always
> Total: 0
> Pass: 0
> Fail:  0
> 
> Why it produce such strange result? I guess it may be the perl ... |
> while pipe make Bash produce strange behavior. Could you please help ?

In bash, commands following a pipe are executed in a subshell, with all
implications of scope WRT variables in a subshell.

You may try your commands in a ksh (AT&T ksh88 or ksh93, but not PDksh).

Janis

> Thanks!
> 
> Regards!
> Bo
0
Janis
5/9/2009 7:05:37 AM
On 5=D4=C29=C8=D5, =CF=C2=CE=E73=CA=B105=B7=D6, Janis Papanagnou <janis_pap=
anag...@hotmail.com>
wrote:
> Bo Yang wrote:
> > Hi,
> >    My script is as following:
>
> > total=3D0;
> > fail=3D0;
> > pass=3D0;
>
> > perl -ne 'if ($_ =3D~ /href=3D\"(.*\.xml)\"/) { print "$1\n"; }' --
> > "$testdir"/alltests.xml | while read test; do
> >     total=3D$((total+1));
> >     if [ some condition ]; then
> >        fail=3D$((fail+1));
> >     fi
> >     if [ some condition ]; then
> >        pass=3D$((pass+1));
> >     fi
> > done
>
> > # Here I print the count result
> > echo "Total: $total";
> > echo "Pass: $pass";
> > echo "Fail:   $fail";
>
> > ------------------------------------------
> > But the final result are always
> > Total: 0
> > Pass: 0
> > Fail:  0
>
> > Why it produce such strange result? I guess it may be the perl ... |
> > while pipe make Bash produce strange behavior. Could you please help ?
>
> In bash, commands following a pipe are executed in a subshell, with all
> implications of scope WRT variables in a subshell.
>
> You may try your commands in a ksh (AT&T ksh88 or ksh93, but not PDksh).

Thanks for you fast reply, Janis!
I can only use Bash in my environment, could you please give me some
advice on how can I change my code ?

Regards!
Bo
0
GB2312
5/9/2009 7:08:49 AM
�� �� wrote:
> On 5��9��, ����3ʱ05��, Janis Papanagnou <janis_papanag...@hotmail.com>
> wrote:
> 
>>Bo Yang wrote:
>>
>>>Hi,
>>>   My script is as following:
>>
>>>total=0;
>>>fail=0;
>>>pass=0;
>>
>>>perl -ne 'if ($_ =~ /href=\"(.*\.xml)\"/) { print "$1\n"; }' --
>>>"$testdir"/alltests.xml | while read test; do
>>>    total=$((total+1));
>>>    if [ some condition ]; then
>>>       fail=$((fail+1));
>>>    fi
>>>    if [ some condition ]; then
>>>       pass=$((pass+1));
>>>    fi
>>>done
>>
>>># Here I print the count result
>>>echo "Total: $total";
>>>echo "Pass: $pass";
>>>echo "Fail:   $fail";
>>
>>>------------------------------------------
>>>But the final result are always
>>>Total: 0
>>>Pass: 0
>>>Fail:  0
>>
>>>Why it produce such strange result? I guess it may be the perl ... |
>>>while pipe make Bash produce strange behavior. Could you please help ?
>>
>>In bash, commands following a pipe are executed in a subshell, with all
>>implications of scope WRT variables in a subshell.
>>
>>You may try your commands in a ksh (AT&T ksh88 or ksh93, but not PDksh).
> 
> 
> Thanks for you fast reply, Janis!
> I can only use Bash in my environment, could you please give me some
> advice on how can I change my code ?

(Strange; environments with bash are usually open to install other software.
Anyway...)

I'd probably use something like this...

perl ... | awk ' { total++ }
  somecond1 { fail++ }
  somecond2 { pass++ }
  END { print "Total:", total
        print "Pass:", pass
        print "Fail:", fail
  } '

OTOH, if I have perl in front of the pipe I'd write the whole awk thing in perl
(i.e. if I kew perl well enough). Or vice versa; incorporate the perl code into
the awk program.

Janis

> 
> Regards!
> Bo
0
Janis
5/9/2009 7:34:35 AM
On 5=D4=C29=C8=D5, =CF=C2=CE=E73=CA=B134=B7=D6, Janis Papanagnou <janis_pap=
anag...@hotmail.com>
wrote:
> =D1=EE =B2=A8 wrote:
> > On 5=D4=C29=C8=D5, =CF=C2=CE=E73=CA=B105=B7=D6, Janis Papanagnou <janis=
_papanag...@hotmail.com>
> > wrote:
>
> >>Bo Yang wrote:
>
> >>>Hi,
> >>>   My script is as following:
>
> >>>total=3D0;
> >>>fail=3D0;
> >>>pass=3D0;
>
> >>>perl -ne 'if ($_ =3D~ /href=3D\"(.*\.xml)\"/) { print "$1\n"; }' --
> >>>"$testdir"/alltests.xml | while read test; do
> >>>    total=3D$((total+1));
> >>>    if [ some condition ]; then
> >>>       fail=3D$((fail+1));
> >>>    fi
> >>>    if [ some condition ]; then
> >>>       pass=3D$((pass+1));
> >>>    fi
> >>>done
>
> >>># Here I print the count result
> >>>echo "Total: $total";
> >>>echo "Pass: $pass";
> >>>echo "Fail:   $fail";
>
> >>>------------------------------------------
> >>>But the final result are always
> >>>Total: 0
> >>>Pass: 0
> >>>Fail:  0
>
> >>>Why it produce such strange result? I guess it may be the perl ... |
> >>>while pipe make Bash produce strange behavior. Could you please help ?
>
> >>In bash, commands following a pipe are executed in a subshell, with all
> >>implications of scope WRT variables in a subshell.
>
> >>You may try your commands in a ksh (AT&T ksh88 or ksh93, but not PDksh)=
..
>
> > Thanks for you fast reply, Janis!
> > I can only use Bash in my environment, could you please give me some
> > advice on how can I change my code ?
>
> (Strange; environments with bash are usually open to install other softwa=
re.
> Anyway...)
>
> I'd probably use something like this...
>
> perl ... | awk ' { total++ }
>   somecond1 { fail++ }
>   somecond2 { pass++ }
>   END { print "Total:", total
>         print "Pass:", pass
>         print "Fail:", fail
>   } '
>
> OTOH, if I have perl in front of the pipe I'd write the whole awk thing i=
n perl
> (i.e. if I kew perl well enough). Or vice versa; incorporate the perl cod=
e into
> the awk program.
>
Ah, indeed, my above script is a simple demo to make the problem
obvious. My real script has to do many other things in while loop, so
change to awk is not possible for me. Anyway, thanks a lot!

Regards!
Bo

0
GB2312
5/9/2009 7:52:25 AM
Bo Yang wrote:

> Why it produce such strange result? I guess it may be the perl ... |
> while pipe make Bash produce strange behavior. Could you please help ?
> Thanks!

Reading the other posts, I know that you need a Bash solution.

So check process substitution.

while .....; do
....
done < <(perl ....)

Also see http://bash-hackers.org/wiki/doku.php/scripting/processtree

J.
0
Jan
5/9/2009 8:18:48 AM
On 5=D4=C29=C8=D5, =CF=C2=CE=E74=CA=B118=B7=D6, Jan Schampera <jan.schamp..=
..@web.de> wrote:
> Bo Yang wrote:
> > Why it produce such strange result? I guess it may be the perl ... |
> > while pipe make Bash produce strange behavior. Could you please help ?
> > Thanks!
>
> Reading the other posts, I know that you need a Bash solution.
>
> So check process substitution.
>
> while .....; do
> ...
> done < <(perl ....)
>
> Also seehttp://bash-hackers.org/wiki/doku.php/scripting/processtree

Yeah, really helpful and solve my problem. Thanks!

Regards!
Bo

0
GB2312
5/9/2009 8:45:30 AM
On Sat, 09 May 2009 00:08:49 -0700, 杨 波 wrote:

> On 5月9日, 下午3时05分, Janis Papanagnou <janis_papanag...@hotmail.com> 
wrote:
>> Bo Yang wrote:
>> > Hi,
>> >    My script is as following:
>>
>> > total=0;
>> > fail=0;
>> > pass=0;
>>
>> > perl -ne 'if ($_ =~ /href=\"(.*\.xml)\"/) { print "$1\n"; }' --
>> > "$testdir"/alltests.xml | while read test; do
>> >     total=$((total+1));
>> >     if [ some condition ]; then
>> >        fail=$((fail+1));
>> >     fi
>> >     if [ some condition ]; then
>> >        pass=$((pass+1));
>> >     fi
>> > done
>>
>> > # Here I print the count result
>> > echo "Total: $total";
>> > echo "Pass: $pass";
>> > echo "Fail:   $fail";
>>
>> > ------------------------------------------ But the final result are
>> > always
>> > Total: 0
>> > Pass: 0
>> > Fail:  0
>>
>> > Why it produce such strange result? I guess it may be the perl ... |
>> > while pipe make Bash produce strange behavior. Could you please help
>> > ?
>>
>> In bash, commands following a pipe are executed in a subshell, with all
>> implications of scope WRT variables in a subshell.
>>
>> You may try your commands in a ksh (AT&T ksh88 or ksh93, but not
>> PDksh).
> 
> Thanks for you fast reply, Janis!
> I can only use Bash in my environment, could you please give me some
> advice on how can I change my code ?
> 
> Regards!
> Bo

Then change it to

perl '....' | {
while read ....
do
.....
done
echo ....
}

This makes the subshell include the echo statements.
0
Icarus
5/9/2009 7:29:42 PM
Reply: