grep exiting with 1 break while loop

grep exiting with 1 break while loop

Post by Christian Erikss » Thu, 12 Sep 2002 00:24:26



In my korn shell I'm using a while loop with I/O redirection:

while read VAR1 VAR2 VAR3
do
  commands
done < input_file

In my commands I'm doing "if grep VAR1 some_file; then ....". The
while loop runs commands for each row in input_file as long as "if
grep VAR1 some_file; then ...." is true, i.e. grep exits with 0. On
the other hand, when this if-statement is false, i.e. grep exits with
1, the loop breaks (not running commands for any subsequent lines in
input_file). What causes this behavior and how do i avoid it?

 
 
 

grep exiting with 1 break while loop

Post by Barry Margoli » Thu, 12 Sep 2002 02:30:55




>In my korn shell I'm using a while loop with I/O redirection:

>while read VAR1 VAR2 VAR3
>do
>  commands
>done < input_file

>In my commands I'm doing "if grep VAR1 some_file; then ....". The
>while loop runs commands for each row in input_file as long as "if
>grep VAR1 some_file; then ...." is true, i.e. grep exits with 0. On
>the other hand, when this if-statement is false, i.e. grep exits with
>1, the loop breaks (not running commands for any subsequent lines in
>input_file). What causes this behavior and how do i avoid it?

When the condition is false, it should execute the else-part of the
if-statement.  If it's not, then I suspect you have a bug in your script.
Post the actual code that's failing.

--

Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

grep exiting with 1 break while loop

Post by Dan Merc » Thu, 12 Sep 2002 03:12:03






>>In my korn shell I'm using a while loop with I/O redirection:

>>while read VAR1 VAR2 VAR3
>>do
>>  commands
>>done < input_file

>>In my commands I'm doing "if grep VAR1 some_file; then ....". The
>>while loop runs commands for each row in input_file as long as "if
>>grep VAR1 some_file; then ...." is true, i.e. grep exits with 0. On
>>the other hand, when this if-statement is false, i.e. grep exits with
>>1, the loop breaks (not running commands for any subsequent lines in
>>input_file). What causes this behavior and how do i avoid it?

> When the condition is false, it should execute the else-part of the
> if-statement.  If it's not, then I suspect you have a bug in your script.
> Post the actual code that's failing.

Wanna bet it drains stdin?

--
Dan Mercer

If responding by email, include the phrase 'from usenet'
in the subject line to avoid spam filtering.

> --

> Genuity, Woburn, MA
> *** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
> Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Opinions expressed herein are my own and may not represent those of my employer.
 
 
 

grep exiting with 1 break while loop

Post by Barry Margoli » Thu, 12 Sep 2002 06:37:49







>>>In my korn shell I'm using a while loop with I/O redirection:

>>>while read VAR1 VAR2 VAR3
>>>do
>>>  commands
>>>done < input_file

>>>In my commands I'm doing "if grep VAR1 some_file; then ....". The
>>>while loop runs commands for each row in input_file as long as "if
>>>grep VAR1 some_file; then ...." is true, i.e. grep exits with 0. On
>>>the other hand, when this if-statement is false, i.e. grep exits with
>>>1, the loop breaks (not running commands for any subsequent lines in
>>>input_file). What causes this behavior and how do i avoid it?

>> When the condition is false, it should execute the else-part of the
>> if-statement.  If it's not, then I suspect you have a bug in your script.
>> Post the actual code that's failing.

>Wanna bet it drains stdin?

I thought of the same thing after I fired off my post, but I was going to
wait until the OP sent in his script to bring it up.

To the OP: does the else-clause run a program like rsh, that reads from its
stdin?  If so, it will inherit the same stdin as the while loop, and suck
up all the remaining lines from input_file.  The solution is to redirect
the input of that command, or if it's rsh you can use the -n option.

--

Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

 
 
 

grep exiting with 1 break while loop

Post by Christian Erikss » Thu, 12 Sep 2002 15:25:16


.....................

Quote:> >> When the condition is false, it should execute the else-part of the
> >> if-statement.  If it's not, then I suspect you have a bug in your script.
> >> Post the actual code that's failing.

> >Wanna bet it drains stdin?

> I thought of the same thing after I fired off my post, but I was going to
> wait until the OP sent in his script to bring it up.

> To the OP: does the else-clause run a program like rsh, that reads from its
> stdin?  If so, it will inherit the same stdin as the while loop, and suck
> up all the remaining lines from input_file.  The solution is to redirect
> the input of that command, or if it's rsh you can use the -n option.

Down below is the main part of the script. I have omitted the
functions mode, logs, dbspaces and checkpoint to keep the posting
shorter. Yes the else-part

if [[ $INFORMIXSQLHOSTS = "" ]]
then
  print "INFORMIXSERVER $INFORMIXSERVER finns inte i $INFORMIXDIR\
/etc/sqlhosts"
else
  print "INFORMIXSERVER $INFORMIXSERVER finns inte i
$INFORMIXSQLHOSTS"
fi

is executed and in that case then the loop stops. In the script I do
some tests on the variables INFORMIXDIR, INFORMIXSERVER and
INFORMIXSQLHOSTS. I do the tests with nested if-clauses that I hope
you can follow. Maybe I shouldn't nest them like that but I think it's
managable. However, the if-clause that's under investigation is:

if [[ $INFORMIXSQLHOSTS = "" ]] && grep -q ^$INFORMIXSERVER[[:space:]]
\
 $INFORMIXDIR/etc/sqlhosts || grep -q ^$INFORMIXSERVER[[:space:]]
$INFORMIXSQLHOSTS

Here I check if the value INFORMIXSERVER is found at the beginning of
a line as a whole word in the file INFORMIXSQLHOSTS or if
INFORMIXSQLHOSTS is the null string I check for a match in the default
file $INFORMIXDIR/etc/sqlhosts also. As long as this if-clause is true
the loop runs for all lines in /opt/bigb/bb/ext/bb-informix.conf but
when it's false it skips subsequent lines. For the script config file
/opt/bigb/bb/ext/bb-informix.conf the rule is that you have to make
entries for INFORMIXDIR and INFORMIXSERVER but INFORMIXSQLHOSTS is
optional.

The script (except definitions of functions mode, logs, dbspaces and
checkpoint):

#
# First load the standard definitions
#
BBHOME=/opt/bigb/bb  # Used for testing the script

if test ! "$BBTMP"; then

. $BBHOME/etc/bbdef.sh  #Include standard definitions

fi

# Set the alarm threasholds for the test. MODEPANIC is set further
down in the
# script due to the fact that the value is not set from the beginning

MODEWARNING="Quiescent Shutdown Initialization"
LOGPANIC="5"
LOGWARNING="50"
DB_SPACE_WARN="95"
DB_SPACE_PANIC="98"
DURATIONPANIC="20"
DURATIONWARNING="5"

#
#############################################################
export INFORMIXDIR
export INFORMIXSERVER
export INFORMIXSQLHOSTS
HOST=$(uname -n)
ORIGINAL_PATH=$PATH

while read INFORMIXDIR INFORMIXSERVER INFORMIXSQLHOSTS
do
    if [[ -a $INFORMIXDIR && -d $INFORMIXDIR && -r $INFORMIXDIR ]]
    then
      if [[ $INFORMIXSQLHOSTS = "" || ( -a $INFORMIXSQLHOSTS || -f \
$INFORMIXSQLHOSTS || -r $INFORMIXSQLHOSTS) ]]
      then
        if [[ $INFORMIXSQLHOSTS = "" ]] && grep -q
^$INFORMIXSERVER[[:space:]] \
 $INFORMIXDIR/etc/sqlhosts || grep -q ^$INFORMIXSERVER[[:space:]]
$INFORMIXSQLHOSTS
        then
          PATH=$ORIGINAL_PATH:$INFORMIXDIR/bin
          mode
          logs
          dbspaces
          checkpoint
        else
          if [[ $INFORMIXSQLHOSTS = "" ]]
          then
            print "INFORMIXSERVER $INFORMIXSERVER finns inte i
$INFORMIXDIR\
/etc/sqlhosts"
          else
            print "INFORMIXSERVER $INFORMIXSERVER finns inte i
$INFORMIXSQLHOSTS"
          fi
        fi
      else
        print "INFORMIXSQLHOSTS $INFORMIXSQLHOSTS existerar inte, ar
inte en \
vanlig fil eller du har inte lasrattigheter pa $INFORMIXSQLHOSTS"
      fi
    else
      print "INFORMIXDIR $INFORMIXDIR existerar inte, ar inte en
katalog \
eller du har inte lasrattigheter pa $INFORMIXDIR"
    fi
done < /opt/bigb/bb/ext/bb-informix.conf

 
 
 

grep exiting with 1 break while loop

Post by Dan Merc » Thu, 12 Sep 2002 22:44:02



DELETIA

Quote:

> while read INFORMIXDIR INFORMIXSERVER INFORMIXSQLHOSTS
> do
>     if [[ -a $INFORMIXDIR && -d $INFORMIXDIR && -r $INFORMIXDIR ]]
>     then
>       if [[ $INFORMIXSQLHOSTS = "" || ( -a $INFORMIXSQLHOSTS || -f \
> $INFORMIXSQLHOSTS || -r $INFORMIXSQLHOSTS) ]]
>       then

Here is the offending line.  You have to understand how the && and ||
operators work.  They are not quite ANDs or ORs.  Think of the operator
not as between two statements but as beginning the second statement.
Now think of || as meaning: "if the current $? is non-zero execute
the following statement" and && as meaning "execute the following statement
if $? is 0"

What you have written is the equivalent of

   if test1 && test2 || test3

So let's see what happens:

   $ false && echo A || echo B
   B

When the first test is false,  and below that would be when
$INFORMIXSQLHOSTS == "",  then the code after the || is executed.
That code is

   grep -q ^$INFORMIXSERVER[[:space:]] $INFORMIXSQLHOSTS

But since $INFORMIXSQLHOSTS == "" it becomes

   grep -q ^$INFORMIXSERVER[[:space:]]

and that reads,  and drains, stdin.  Had you placed the
$INFORMIXSQLHOSTS in quotes,  you would have gotten an error
that would have pointed you in the right direction.
You should also use quotes on the pattern just to protect yourself
from errant data.

Your test should be:

   if [[ -z $INFORMIXSQLHOSTS ]] && {
      grep -q "^$INFORMIXSERVER[[:space:]]" "$INFORMIXDIR/etc/sqlhosts" ||
      grep -q "^$INFORMIXSERVER[[:space:]]" "$INFORMIXSQLHOSTS"; }

--
Dan Mercer

If responding by email, include the phrase 'from usenet'
in the subject line to avoid spam filtering.

Quote:>         if [[ $INFORMIXSQLHOSTS = "" ]] && grep -q
> ^$INFORMIXSERVER[[:space:]] \
>  $INFORMIXDIR/etc/sqlhosts || grep -q ^$INFORMIXSERVER[[:space:]]
> $INFORMIXSQLHOSTS
>         then
>           PATH=$ORIGINAL_PATH:$INFORMIXDIR/bin
>           mode
>           logs
>           dbspaces
>           checkpoint
>         else
>           if [[ $INFORMIXSQLHOSTS = "" ]]
>           then
>             print "INFORMIXSERVER $INFORMIXSERVER finns inte i
> $INFORMIXDIR\
> /etc/sqlhosts"
>           else
>             print "INFORMIXSERVER $INFORMIXSERVER finns inte i
> $INFORMIXSQLHOSTS"
>           fi
>         fi
>       else
>         print "INFORMIXSQLHOSTS $INFORMIXSQLHOSTS existerar inte, ar
> inte en \
> vanlig fil eller du har inte lasrattigheter pa $INFORMIXSQLHOSTS"
>       fi
>     else
>       print "INFORMIXDIR $INFORMIXDIR existerar inte, ar inte en
> katalog \
> eller du har inte lasrattigheter pa $INFORMIXDIR"
>     fi
> done < /opt/bigb/bb/ext/bb-informix.conf

Opinions expressed herein are my own and may not represent those of my employer.
 
 
 

grep exiting with 1 break while loop

Post by Christian Eriksso » Fri, 13 Sep 2002 09:31:08




  > DELETIA
  >
  >>while read INFORMIXDIR INFORMIXSERVER INFORMIXSQLHOSTS
  >>do
  >>    if [[ -a $INFORMIXDIR && -d $INFORMIXDIR && -r $INFORMIXDIR ]]
  >>    then
  >>      if [[ $INFORMIXSQLHOSTS = "" || ( -a $INFORMIXSQLHOSTS || -f \
  >>$INFORMIXSQLHOSTS || -r $INFORMIXSQLHOSTS) ]]
  >>      then
  >
  >
  > Here is the offending line.  You have to understand how the && and ||
  > operators work.  They are not quite ANDs or ORs.  Think of the operator
  > not as between two statements but as beginning the second statement.
  > Now think of || as meaning: "if the current $? is non-zero execute
  > the following statement" and && as meaning "execute the following
statement
  > if $? is 0"

I know these operators short circuit. Your right about the fact that
it's a flaw in this if-clause.

  >
  > What you have written is the equivalent of
  >
  >    if test1 && test2 || test3
  >
  > So let's see what happens:
  >
  >    $ false && echo A || echo B
  >    B
  >
  > When the first test is false,  and below that would be when
  > $INFORMIXSQLHOSTS == "",  then the code after the || is executed.

I don't agree with you here, the test below is false when
$INFORMIXSQLHOSTS is not null. "grep -q ^$INFORMIXSERVER[[:space:]]
$INFORMIXSQLHOSTS" will be executed when [[ $INFORMIXSQLHOSTS = "" ]] is
false and/or when "grep -q ^$INFORMIXSERVER[[:space:]]
$INFORMIXDIR/etc/sqlhosts" is false. The mistake is that "grep -q
^$INFORMIXSERVER[[:space:]] $INFORMIXSQLHOSTS" gets executed even if
$INFORMIXSQLHOSTS is null, your right about that, but that's caused by
test2 being false not test1.

  > That code is
  >
  >    grep -q ^$INFORMIXSERVER[[:space:]] $INFORMIXSQLHOSTS
  >
  > But since $INFORMIXSQLHOSTS == "" it becomes
  >
  >    grep -q ^$INFORMIXSERVER[[:space:]]
  >
  > and that reads,  and drains, stdin.  Had you placed the
  > $INFORMIXSQLHOSTS in quotes,  you would have gotten an error
  > that would have pointed you in the right direction.
  > You should also use quotes on the pattern just to protect yourself
  > from errant data.

Thank's for this information.

  >
  > Your test should be:
  >
  >    if [[ -z $INFORMIXSQLHOSTS ]] && {
  >       grep -q "^$INFORMIXSERVER[[:space:]]"
"$INFORMIXDIR/etc/sqlhosts" ||
  >       grep -q "^$INFORMIXSERVER[[:space:]]" "$INFORMIXSQLHOSTS"; }

I think my test should be, with the quotes as you suggest:

if  { [[ -z $INFORMIXSQLHOSTS ]] &&
     grep -q "^$INFORMIXSERVER[[:space:]]" "$INFORMIXDIR/etc/sqlhosts" } ||
     { [[ -n $INFORMIXSQLHOSTS ]] && grep -q "^$INFORMIXSERVER[[:space:]]"
"$INFORMIXSQLHOSTS" }

This way I grep in the default file $INFORMIXDIR/etc/sqlhosts if
$INFORMIXSQLHOSTS is null as before but grep in the file
$INFORMIXSQLHOSTS only if it's not null thanks to the new [[ -n
$INFORMIXSQLHOSTS ]].

I shall test the code and get back here to tell if it solved the problem.

  >

  >phrase 'from usenet' in the subject line to avoid spam filtering.
  >
  >>        if [[ $INFORMIXSQLHOSTS = "" ]] && grep -q
  >> ^$INFORMIXSERVER[[:space:]] \
  >>  $INFORMIXDIR/etc/sqlhosts || grep -q ^$INFORMIXSERVER[[:space:]]
  >> $INFORMIXSQLHOSTS
  >>         then
  >>           PATH=$ORIGINAL_PATH:$INFORMIXDIR/bin
  >>           mode
  >>           logs
  >>           dbspaces
  >>           checkpoint
  >>         else
  >>           if [[ $INFORMIXSQLHOSTS = "" ]]
  >>           then
  >>             print "INFORMIXSERVER $INFORMIXSERVER finns inte i
  >> $INFORMIXDIR\
  >> /etc/sqlhosts"
  >>           else
  >>             print "INFORMIXSERVER $INFORMIXSERVER finns inte i
  >> $INFORMIXSQLHOSTS"
  >>           fi
  >>         fi
  >>       else
  >>         print "INFORMIXSQLHOSTS $INFORMIXSQLHOSTS existerar inte, ar
  >> inte en \
  >> vanlig fil eller du har inte lasrattigheter pa $INFORMIXSQLHOSTS"
  >>       fi
  >>     else
  >>       print "INFORMIXDIR $INFORMIXDIR existerar inte, ar inte en
  >>katalog \
  >> eller du har inte lasrattigheter pa $INFORMIXDIR"
  >>    fi
  >> done < /opt/bigb/bb/ext/bb-informix.conf

  >Opinions expressed herein are my own and may not represent those of my
  >employer.

 
 
 

grep exiting with 1 break while loop

Post by Christian Eriksso » Mon, 16 Sep 2002 00:22:20





...............................
 >
 > I think my test should be, with the quotes as you suggest:
 >
 > if  { [[ -z $INFORMIXSQLHOSTS ]] &&
 >     grep -q "^$INFORMIXSERVER[[:space:]]" "$INFORMIXDIR/etc/sqlhosts"
Quote:} ||

 >     { [[ -n $INFORMIXSQLHOSTS ]] && grep -q "^$INFORMIXSERVER[[:space:]]"
 > "$INFORMIXSQLHOSTS" }
 >
 > This way I grep in the default file $INFORMIXDIR/etc/sqlhosts if
 > $INFORMIXSQLHOSTS is null as before but grep in the file
 > $INFORMIXSQLHOSTS only if it's not null thanks to the new [[ -n
 > $INFORMIXSQLHOSTS ]].
 >
 > I shall test the code and get back here to tell if it solved the problem.

Yes, the code worked with some adjustments. I had to add semicolons to
the blocks {}. I also use '= ""' instead of -z and '!= ""' instead of
-n. The if-clause I now use is:

if  { [[ $INFORMIXSQLHOSTS = "" ]] &&
       grep -q "^$INFORMIXSERVER[[:space:]]"
"$INFORMIXDIR/etc/sqlhosts";} ||
       { [[ $INFORMIXSQLHOSTS != "" ]] && grep -q
"^$INFORMIXSERVER[[:space:]]" "$INFORMIXSQLHOSTS";}

Thanks for the help to identify the if-clause as the source of the problem.

Regards Christian Eriksson.

 
 
 

1. Non-zero exit code breaks bash loop

Hi. I have a simple script that untars some tarfiles. In the script is
the following loop:

for i in *.tar
do
    tar -xf $i
done

The problem is that if the tar program exits with a non-zero exit code,
the loop breaks. Does anyone know how to prevent the loop from
breaking?

Thanks.

David Rodrigues

2. file / directory transfer

3. break one loop and skip one iteration of outer loop

4. (g)mplayer has jagged edges/fine black lines under fullscreen

5. grep sTerm * | grep -v grep ???

6. Dip server problems

7. tail | grep | grep | grep

8. BOUND ports with netstat

9. Press Ctrl-D whiling inputting

10. capturing grep output in a foreach loop... (LONG)

11. Help With Shell Script.... goes in a loop and grep script req.

12. test grep in while loop

13. Exit statu and loop question