It is currently Sun, 27 Jul 2014 23:14:06 GMT



 
Author Message
 ksh, return codes, m4, and pipes

Hi, I am trying to make one of my korn shells more efficient.  I
have a line that looks sort of like this:

        m4 < file1 | sed '/^$/d' > file2

The sed statement removes the blank lines from the m4 processed file
(hoping to avoid dnls).  To make the code more robust I decided I
needed the return code from the m4 command.  This changed the code
into:

        m4 < file1 > file2
        if (( $? > 0 )) ; then
                exit or log or whine or something
        fi
        sed '/^$/d' < file2 > file3

I was hoping for a more efficient way to do this.  What I really want
is to not create the extra temp file, "file2" (disk I/O being costly).
I've tried numerous things and have not found a good solution.  I've
tried trapping the error but ksh does not get the err when the command
is piped.  I've tried setting the standard err to a variable --
something like:

rcode=$(m4 < file1 | sed '/^$/d' > file2) or

        -in this case rcode is not set.

rcode=$(m4 < file1 2>&1 | sed '/^$/d' > file2)

        -in this case rcode is set but m4 output gets muddled.  Does
anyone know if there is a way to grab the m4 return code without
breaking up the pipe?  This is not that big of a deal, but I thought
I should be able to do it...   THANKS

moss.



 Sat, 25 Apr 1998 03:00:00 GMT   
 ksh, return codes, m4, and pipes
In article <47oo2q$...@tiptoe.fhda.edu>, bsh20...@challenger.fhda.edu (Brian S Hiles ) writes:

|> Moss Oss (m...@hill.gnu.ai.mit.edu) wrote:
|> : Hi, I am trying to make one of my korn shells more efficient.  I
|> : have a line that looks sort of like this:
|> :         m4 < file1 | sed '/^$/d' > file2
|> : The sed statement removes the blank lines from the m4 processed file
|> : (hoping to avoid dnls).  To make the code more robust I decided I
|> : needed the return code from the m4 command.  This changed the code
|> : into:
|> :         m4 < file1 > file2
|> :         if (( $? > 0 )) ; then
|> :                 exit or log or whine or something
|> :         fi
|> :         sed '/^$/d' < file2 > file3
|> : I was hoping for a more efficient way to do this.  What I really want
|> : is to not create the extra temp file, "file2" (disk I/O being costly).
|> : I've tried numerous things and have not found a good solution.  I've
|> : tried trapping the error but ksh does not get the err when the command
|> : is piped.  I've tried setting the standard err to a variable --
|> [cut]

|> m4 <file1 && sed -n '/^$/!w file2'

This will make m4 dump the output to your terminal, and sed will wait
for your input.  Better try this:

if ! m4 < file1; then echo m4 failed >&2; fi | sed '/^$/d' > file3
--
Andreas Schwab                                      "And now for something
sch...@issan.informatik.uni-dortmund.de              completely different"



 Sun, 26 Apr 1998 03:00:00 GMT   
 ksh, return codes, m4, and pipes

   |> :      m4 < file1 > file2
   |> :      if (( $? > 0 )) ; then
   |> :              exit or log or whine or something
   |> :      fi
   |> :      sed '/^$/d' < file2 > file3
   |> : I was hoping for a more efficient way to do this.  What I really want
   |> : is to not create the extra temp file, "file2" (disk I/O being costly).
   |> : I've tried numerous things and have not found a good solution.  I've
   |> : tried trapping the error but ksh does not get the err when the command
   |> : is piped.  I've tried setting the standard err to a variable --

   |> m4 <file1 && sed -n '/^$/!w file2'

   This will make m4 dump the output to your terminal, and sed will wait
   for your input.  Better try this:

   if ! m4 < file1; then echo m4 failed >&2; fi | sed '/^$/d' > file3

Thanks for the response - this is closer than what I got but I'm still
having a couple problems.  The first is ksh for some reason isn't
coping with the "!" in front of my m4 line.  The second is in the then
part of the code: I want to issue a warning message and continue (the
if is in a loop).  It does not continue and sed is still called and
processing goes forward.  In fact, ksh does not let me do a continue,
break or exit in this part of the if code (the pipe screws it up I
would guess, since it is started at the same time...)  My code looked
something like this:

        if m4 < file ; then :
        else
                print "bombed"
                continue
        fi | sed '/^$/d' > file3

the continue here chokes...  kind of an interesting dilemma.  I
thought wisely place brackets {} could also solve the problem, but I
have yet to figure out how to work these with the redirection.  Ideas?

moss.



 Sun, 26 Apr 1998 03:00:00 GMT   
 ksh, return codes, m4, and pipes
m...@hill.gnu.ai.mit.edu wrote in
<MOSS.95Nov8164...@hill.gnu.ai.mit.edu>:

| My code looked something like this:
|
|       if m4 < file ; then :
|       else
|               print "bombed"
|               continue
|       fi | sed '/^$/d' > file3
|
| the continue here chokes...  kind of an interesting dilemma.

"Continue" is used for resuming a for/while/until loop; it is meaningless
inside an if structure (unless that if structure is itself inside a loop).

What you're piping to sed is either the word "bombed" if m4 returns failure
or nothing (the output of ":") if m4 returns success.  I don't know why
you're intent on not invoking sed if m4 fails; I'd do just this, though
I'd use grep intead of sed:

  { m4 < file || print -u2 bombed ;} | grep . > file3

That would create file3 in all cases, though file3 would be empty if m4
returns failure.  But to avoid calling grep at all if m4 fails, let's see
what we can do:

   if m4 < file > tempfile
   then grep . tempfile > file3 ; rm -f tempfile
   else print "bombed"
   fi

A named pipe probably wouldn't be of much help here, since the read has
to start for the write to proceed, and we won't know the exit status of
the write at that point.  A coprocess might help, but I've never understood
those things.  Otherwise the temporary file is needed.



 Mon, 27 Apr 1998 03:00:00 GMT   
 ksh, return codes, m4, and pipes
On 07 Nov 1995 00:18:53 GMT, m...@hill.gnu.ai.mit.edu (Moss Oss) said:

One way to do this is to use redirection inside backquotes, but it isn't
pretty.  Use something like

    return=`exec 3>&1; { m4 <file1; echo $? >&3; } | sed '/^$/d' >file2`

which will leave $return holding m4's exit value.  Breaking this down,

    return=`...`        set $return to the output of ``
    exec 3>&1            make fd 3 point at ``
    {...} | sed         run {...} with stdout pointing at sed
    m4 <file1                run m4 with output to stdout, which is pointing at sed
    echo $? >&3          echo the $? to fd 3, which is still ``

.  Whether this is actually more efficient than using an an additional
intermediate temporary file and saving all those pipes and forks (and
whether it's worth it, in light of higher maintenance costs) I'm not
sure.  I'd probably just stick with the additional temporary file, or
perhaps I'd benchmark the two techniques if it was really important.

PS:  If you're trying to avoid `dnl's when defining macros or the like
you might instead bracket your macro definitions between `divert(-1)'
and `divert`'dnl'.

--
Roderick Schertler
roder...@gate.net



 Sat, 02 May 1998 03:00:00 GMT   
 
   [ 5 post ] 

Similar Threads

1. Return code of pipe command (not entire pipe)

2. Obtain return code before pipe

3. return code from piped function

4. Check return code of commands in a pipe?

5. piping and return codes in bsh

6. Return codes in trap handlers in ksh

7. carriage return gnu m4 autoconf

8. Help: Returning a return code to a program

9. Help: Returning a return code to a program

10. Return Code or Error Code with patches


 
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software