function exit does not work with pipe

function exit does not work with pipe

Post by Christophe Brugn » Sat, 09 Dec 2000 02:12:45



Hi all,

I have some trouble with trying to exit a ksh script in a function.
My code without pipe:

#!/bin/ksh
function f {
        echo f
        exit 1

Quote:}

echo begin
f
echo end

the output is :
begin
f

The exit works as supposed to.

But with a pipe on the function :
#!/bin/ksh
function f {
        echo f
        exit 1

Quote:}

echo begin
f | cat
echo end

the output is :
begin
f
end

I suppose that even with a function (as a script), the use of a pipe
executes the command in a subshell and so the exit exits only the
subshell.
What kind of solution do you use in this case to exit from the whole
script ? I would like to do this to write an error function that
display a message and abort the whole script.

Any advice ?

--

Christophe Brugne
--------------------------------

site web: http://cbrugne.free.fr

Sent via Deja.com http://www.deja.com/
Before you buy.

 
 
 

function exit does not work with pipe

Post by Christophe Brugn » Sat, 09 Dec 2000 23:48:30



> >But with a pipe on the function :
> >#!/bin/ksh
> >function f {
> >        echo f
> >        exit 1
> >}
> >echo begin
> >f | cat
> >echo end

> >the output is :
> >begin
> >f
> >end

> >I suppose that even with a function (as a script), the use of a pipe
> >executes the command in a subshell and so the exit exits only the
> >subshell.

> Correct.

> >What kind of solution do you use in this case to exit from the whole
> >script ? I would like to do this to write an error function that
> >display a message and abort the whole script.

> #!/bin/ksh
> function f {
>         echo f
>         kill $$
> }
> echo begin
> f | cat
> echo end

>            --Ken Pizzini

Sorry it does not work : try this
#!/bin/ksh
function ferr2 {
    echo begin ferr2
    kill $$
    echo end ferr2

Quote:}

function frun1 {
    echo begin frun1
    ferr2
    echo end frun1

Quote:}

function fmain0 {
    echo begin fmain0
    frun1 | cat
    echo end fmain0

Quote:}

echo begin
echo "before bla bla"
fmain0
echo "after bla bla"
echo end

The output is :
begin
before bla bla
begin fmain0
begin frun1
begin ferr2
end ferr2
end frun1
zsh: terminated  toto

and with an exit 1 in place of kill $$ :
begin
before bla bla
begin fmain0
begin frun1
begin ferr2
end fmain0
after bla bla
end

With kill, the main process is killed but the subshell goes on working.
You can browse all the subprocess running and kill them too but this is
really heavy to use a missile to kill a mouse.
--

Christophe Brugne
--------------------------------

site web: http://cbrugne.free.fr

Sent via Deja.com http://www.deja.com/
Before you buy.

 
 
 

function exit does not work with pipe

Post by Larr » Sun, 10 Dec 2000 01:29:56


You need to use "return 1" where you have "exit 1".
If this script is being called by another script... then something like
this:

#!/bin/ksh

function bob
{
   so stuff
   return $?

Quote:}

# Main routine

echo Begin
bob
SAVE_STS=$?

if [[ $SAVE_STS = 0 ]]
then
   do more stuff saving $? into SAVE_STS as needed
fi

exit $SAVE_STS


> Hi all,

> I have some trouble with trying to exit a ksh script in a function.
> My code without pipe:

> #!/bin/ksh
> function f {
>         echo f
>         exit 1
> }
> echo begin
> f
> echo end

> the output is :
> begin
> f

> The exit works as supposed to.

> But with a pipe on the function :
> #!/bin/ksh
> function f {
>         echo f
>         exit 1
> }
> echo begin
> f | cat
> echo end

> the output is :
> begin
> f
> end

> I suppose that even with a function (as a script), the use of a pipe
> executes the command in a subshell and so the exit exits only the
> subshell.
> What kind of solution do you use in this case to exit from the whole
> script ? I would like to do this to write an error function that
> display a message and abort the whole script.

> Any advice ?

> --

> Christophe Brugne
> --------------------------------

> site web: http://cbrugne.free.fr

> Sent via Deja.com http://www.deja.com/
> Before you buy.

 
 
 

function exit does not work with pipe

Post by Christophe Brugn » Wed, 13 Dec 2000 16:48:43


It will not work if you pipe the call of your function as with 'bob |
grep "blabla"' because of the loss of the return code. It will be the
one of grep and not the one of bob.
It exists solutions for this (ugly: saving intermediate status in a
temporary file, more beautiful but heavier: using a coprocess) but the
code becomes more complex.
Moreover when you use several imbricated functions, your code becomes
really heavy with enormous "if" to avoid executing all the code
following a function call.
Any other idea ?

> You need to use "return 1" where you have "exit 1".
> If this script is being called by another script... then something
like
> this:

> #!/bin/ksh

> function bob
> {
>    so stuff
>    return $?
> }

> # Main routine

> echo Begin
> bob
> SAVE_STS=$?

> if [[ $SAVE_STS = 0 ]]
> then
>    do more stuff saving $? into SAVE_STS as needed
> fi

> exit $SAVE_STS


> > Hi all,

> > I have some trouble with trying to exit a ksh script in a function.
> > My code without pipe:

> > #!/bin/ksh
> > function f {
> >         echo f
> >         exit 1
> > }
> > echo begin
> > f
> > echo end

> > the output is :
> > begin
> > f

> > The exit works as supposed to.

> > But with a pipe on the function :
> > #!/bin/ksh
> > function f {
> >         echo f
> >         exit 1
> > }
> > echo begin
> > f | cat
> > echo end

> > the output is :
> > begin
> > f
> > end

> > I suppose that even with a function (as a script), the use of a pipe
> > executes the command in a subshell and so the exit exits only the
> > subshell.
> > What kind of solution do you use in this case to exit from the whole
> > script ? I would like to do this to write an error function that
> > display a message and abort the whole script.

> > Any advice ?

> > --

> > Christophe Brugne
> > --------------------------------

> > site web: http://cbrugne.free.fr

> > Sent via Deja.com http://www.deja.com/
> > Before you buy.

--

Christophe Brugne
--------------------------------

site web: http://cbrugne.free.fr

Sent via Deja.com http://www.deja.com/
Before you buy.

 
 
 

function exit does not work with pipe

Post by Dan Merc » Thu, 14 Dec 2000 02:17:49




> It will not work if you pipe the call of your function as with 'bob |
> grep "blabla"' because of the loss of the return code. It will be the
> one of grep and not the one of bob.
> It exists solutions for this (ugly: saving intermediate status in a
> temporary file, more beautiful but heavier: using a coprocess) but the
> code becomes more complex.
> Moreover when you use several imbricated functions, your code becomes
> really heavy with enormous "if" to avoid executing all the code
> following a function call.
> Any other idea ?

Only the obvious - redesigning your script.  The whole point of
functions is to run them in the current shell instance.  Running
them as the head of a pipeline,  forcing them into a subshell,
destroys the whole rationale.  Why do you want to pipe a function
to another process?  what do you hope to gain by that.  It's like
that old joke of the guy who goes to the doctor and says it hurts when
he raises his arm above his head and the doctor says "Don't do that".
What may be humorously bad advice from a doctor is usually the right
advice in prgramming.  I cannot tell you how many times I've seen
posts from people trying to do the impossible when a modest re-design
would cure their problems.  But they stubbornly prefer their
Rube Goldbrick designs to a proper design.  Go figure!

--
Dan Mercer

 
 
 

function exit does not work with pipe

Post by Christophe Brugn » Thu, 14 Dec 2000 20:29:30






> > It will not work if you pipe the call of your function as with 'bob
|
> > grep "blabla"' because of the loss of the return code. It will be
the
> > one of grep and not the one of bob.
> > It exists solutions for this (ugly: saving intermediate status in a
> > temporary file, more beautiful but heavier: using a coprocess) but
the
> > code becomes more complex.
> > Moreover when you use several imbricated functions, your code
becomes
> > really heavy with enormous "if" to avoid executing all the code
> > following a function call.
> > Any other idea ?

> Only the obvious - redesigning your script.  The whole point of
> functions is to run them in the current shell instance.  Running
> them as the head of a pipeline,  forcing them into a subshell,
> destroys the whole rationale.  Why do you want to pipe a function
> to another process?  what do you hope to gain by that.  It's like
> that old joke of the guy who goes to the doctor and says it hurts when
> he raises his arm above his head and the doctor says "Don't do that".
> What may be humorously bad advice from a doctor is usually the right
> advice in prgramming.  I cannot tell you how many times I've seen
> posts from people trying to do the impossible when a modest re-design
> would cure their problems.  But they stubbornly prefer their
> Rube Goldbrick designs to a proper design.  Go figure!

Yes, indeed :-) , for the moment the only way I have found to avoid the
non script exit by the exit command is to avoid piping functions. But I
don't find so far from the standard to use them to produce output able
to be simply filtered by grep or another command.

For instance, I am currently working on sending email by shell script.
I like the idea to prepare the mail by a generic function (in a shell
library I include in my main script) and then pipe its output to
sendmail. I find nice to have the possibility to exit the script right
away if I encounter a fatal error without executing the code after
myfunction | sendmail. Today the "non exit with pipe problem" is my
only problem and I find pratical to use generic function libraries.

As you said, maybe I should redesign my scripts architecture (which is
today generic functions in libraries, included in main scripts). The
solution could be to create external scripts and not libraries to show
clearly the creation of subshells and so managing the return status. My
aim is (of course) to avoid a too heavy code and too much temporary
files creation. For the moment this aim is reached well with piping.
But I remain stuck by the exit problem.

I am not so stubborn :-). I am open to any suggestion from your
experience and the choice you have made, above all if they match the
principle "small and simple is beautiful". You know my aims, what would
you suggest and what is your design ?

--
Christophe Brugne
--------------------------------

site web: http://cbrugne.free.fr

Sent via Deja.com
http://www.deja.com/

 
 
 

function exit does not work with pipe

Post by Dan Merc » Thu, 14 Dec 2000 23:26:41


One thing you can try:

function format_mail
   {
   print ....
   ...
   if [[ -z $MAIL_ADDR ]]
      then
      print -u2 "Error - no mail addresses supplied"
      exit 1
   fi
   }

exec 3<&0 4>&1             # save stdin and stdout
/usr/sbin/sendmail -t |&   # put sendmail in background
exec <&p >&p               # put sendmail process as piping to stdin
                           # and stderr
format_mail
exec <&- >&-               # close stdin and stdout
exec <&3 >&4               # reset to original
exec 3<&- 4>&-             # close dup's

Even that bit of plumbing can be placed in a function call.

--
Dan Mercer





>> Only the obvious - redesigning your script.  The whole point of
>> functions is to run them in the current shell instance.  Running
>> them as the head of a pipeline,  forcing them into a subshell,
>> destroys the whole rationale.  Why do you want to pipe a function
>> to another process?  what do you hope to gain by that.  It's like
>> that old joke of the guy who goes to the doctor and says it hurts when
>> he raises his arm above his head and the doctor says "Don't do that".
>> What may be humorously bad advice from a doctor is usually the right
>> advice in prgramming.  I cannot tell you how many times I've seen
>> posts from people trying to do the impossible when a modest re-design
>> would cure their problems.  But they stubbornly prefer their
>> Rube Goldbrick designs to a proper design.  Go figure!

> Yes, indeed :-) , for the moment the only way I have found to avoid the
> non script exit by the exit command is to avoid piping functions. But I
> don't find so far from the standard to use them to produce output able
> to be simply filtered by grep or another command.

> For instance, I am currently working on sending email by shell script.
> I like the idea to prepare the mail by a generic function (in a shell
> library I include in my main script) and then pipe its output to
> sendmail. I find nice to have the possibility to exit the script right
> away if I encounter a fatal error without executing the code after
> myfunction | sendmail. Today the "non exit with pipe problem" is my
> only problem and I find pratical to use generic function libraries.

> As you said, maybe I should redesign my scripts architecture (which is
> today generic functions in libraries, included in main scripts). The
> solution could be to create external scripts and not libraries to show
> clearly the creation of subshells and so managing the return status. My
> aim is (of course) to avoid a too heavy code and too much temporary
> files creation. For the moment this aim is reached well with piping.
> But I remain stuck by the exit problem.

> I am not so stubborn :-). I am open to any suggestion from your
> experience and the choice you have made, above all if they match the
> principle "small and simple is beautiful". You know my aims, what would
> you suggest and what is your design ?

> --
> Christophe Brugne
> --------------------------------

> site web: http://cbrugne.free.fr

> Sent via Deja.com
> http://www.deja.com/

 
 
 

1. exiting from a function that is piped to tee

Hello,

   I'm having a problem with a ksh script.  Here's my problem

my_exit()
{
  exit 5

my_exit | tee log.txt

This script will not return 5, but rather, when exit is called,
returns to after the my_exit call and then exits, returning 0 to the
shell.  I tried to use a return variable:

my_exit()
{
  returnStatue=5
  exit

returnStatus=0
my_exit | tee log.txt
exit $returnStatus

However, no matter what I try, I cannot get it to save the value of
returnStatus through the exit call.  Any ideas on how to get around
this?  I could write the exit code out into a file and read it at the
end, but that seems like a cheap workaround.

Any help would be greatly appreciated.

2. MH for Linux

3. unix shell script ignores 'exit' when in function that is piped to tee

4. rrdtool, IEEE math, isinf

5. ksh -x does not work on function inside a function

6. Help: Internet Connection Prob.

7. exit status of the command in pipe from shell & named pipe

8. No CD drive or internet connection

9. Exit status in trapped exit function

10. ncftp .open macro not doing bye or exit

11. Doing dead function elimination without -finline-functions in 2.95.2?

12. makefile: exit 0 does not exit!