Re: Error code from a shell pipeline.

2003-10-25 Thread Oleg Goldshmidt

Tzafrir Cohen [EMAIL PROTECTED] writes:

 On Fri, Oct 24, 2003 at 10:47:22PM +0200, Oleg Goldshmidt wrote:
  Shlomi Fish [EMAIL PROTECTED] writes:
  
   On Fri, 24 Oct 2003, Beni Cherniavsky wrote:
   
Shlomi Fish wrote on 2003-10-12:
   
 I want that if one of the (first) components of the pipeline exits with an
 error code, I'll know about it somehow. How?

info bash --index PIPESTATUS
   
   
   Cool thanks.
  
  Depending on your needs you may also use the -e option to the shell
  (should work for most Bourne shell and csh descendants), the option
  will make the shell exit if any of the commands in the pipeline fails.
  
  $ true | false | true
  $ echo $?
  0
  $ bash -e true | false | true
  true | false | true: true | false | true: No such file or directory
  $ echo $?
  1
 
 This is because you tried running a script from a file called
 true | false | true
 
 However:
 
 $ set -e
 $ true | false | true
 $ echo $?
 0
 
 So setting that doesn't make an error from the middle of a pipe show.

Hmm, this seems to be true. What is weird about it, is that it is
supposed to do what I said. At least that is the way I used to read
the bash documentation and also the make documentation (which is where
I learned about -e from N years ago) - see below.

Check http://www.gnu.org/manual/make-3.77/html_node/make_43.html that
says

Here is the pattern rule to generate a file of dependencies (i.e., a
makefile) called `name.d' from a C source file called `name.c':

%.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $ \
  | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\''  $@; \
  [ -s $@ ] || rm -f $@'

See section Defining and Redefining Pattern Rules, for information on
defining pattern rules. The `-e' flag to the shell makes it exit
immediately if the $(CC) command fails (exits with a nonzero
status). Normally the shell exits with the status of the last command
in the pipeline (sed in this case), so make would not notice a nonzero
status from the compiler.

Now, I created the following C file

#include foo.h

int main(void) { return 0; }

(cpp should fail because there is no foo.h), and the following
makefile:

%.d: %.c
$(SHELL) -ec '$(CC) -M $(CPPFLAGS) $ \
| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\''  $@'

(I don't want foo.d removed if it contains nothing, otherwise it is
identical to the example in the manual).

Guess what: make does not notice a nonzero status from the compiler
with or without -e.

So I got curious, and added

SHELL := csh

to the makefile, and - lo and behold! - it worked (csh is a symbolic
link to tcsh, and it works for both).

Now, man tcsh says

   -e  The  shell  exits  if  any  invoked command terminates
   abnormally or yields a non-zero exit status.

To compare, man bash says (for set builtin)

 -e  Exit  immediately  if a simple command (see
  SHELL GRAMMAR above) exits with a  non-zero
  status.   The  shell  does  not exit if the
  command that fails is part of an  until  or
  while  loop,  part of an if statement, part
  of a  or || list,  or  if  the  command's
  return  value  is  being inverted via !.  A
  trap on ERR, if set, is executed before the
  shell exits.
  
Further RTFMing (man bash is at your service) uncovered that bash
distinguishes between simple commands, pipelines, and lists, and the
-e applies to simple commands only, as per above.

So it turns out that bash and tcsh behave differently. I apologize for
my misleading post - it only applies to t?csh, it seems, not to bash
(nor to zsh). I find it rather curious that the make documentation
does not mention the difference.

Now, I don't know what the rationale for bash behaviour is. It seems
to me that the way tcsh behaves is pretty useful.

-- 
Oleg Goldshmidt | [EMAIL PROTECTED]

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-25 Thread Oron Peled
On Saturday 25 October 2003 14:47, Oleg Goldshmidt wrote:
 Now, I don't know what the rationale for bash behaviour is. It seems
 to me that the way tcsh behaves is pretty useful.

Probably some POSIX compliance requirement. I'm too lazy to search
now GO-SOLO - The single Unix specification, but may do it later
under sufficient pressure :-)

-- 
Oron Peled Voice/Fax: +972-4-8228492
[EMAIL PROTECTED]  http://www.actcom.co.il/~oron

Normal people ... believe that if it ain't broke, don't fix it.
Engineers believe that if it ain't broke, it doesn't have enough
features ... yet. -- Scott Adams


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-24 Thread Beni Cherniavsky
Shlomi Fish wrote on 2003-10-12:

 I want that if one of the (first) components of the pipeline exits with an
 error code, I'll know about it somehow. How?

info bash --index PIPESTATUS

$ true | false | true | false; echo [EMAIL PROTECTED]
0 1 0 1
$ { true | false | true | false; }; echo [EMAIL PROTECTED]
0 1 0 1

However, using parenthesis you launch the whole pipeline in a subshell
so it won't work:

$ ( true | false | true | false; ); echo [EMAIL PROTECTED]
1

Also, it mysteriously seems to be lost after every command in
interactive mode:

$ true | false | true | false
$ echo [EMAIL PROTECTED]
0

Although it does work in non-interactive mode:

$ echo $'true | false | true | false\necho [EMAIL PROTECTED]' | sh
0 1 0 1

If you want a less fragile approach, Oded Arbel gave a good advice.

-- 
Beni Cherniavsky [EMAIL PROTECTED]


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-24 Thread Shlomi Fish
On Fri, 24 Oct 2003, Beni Cherniavsky wrote:

 Shlomi Fish wrote on 2003-10-12:

  I want that if one of the (first) components of the pipeline exits with an
  error code, I'll know about it somehow. How?
 
 info bash --index PIPESTATUS


Cool thanks.

 $ true | false | true | false; echo [EMAIL PROTECTED]
 0 10 1
 $ { true | false | true | false; }; echo [EMAIL PROTECTED]
 0 1 0 1

 However, using parenthesis you launch the whole pipeline in a subshell
 so it won't work:

 $ ( true | false | true | false; ); echo [EMAIL PROTECTED]
 1

 Also, it mysteriously seems to be lost after every command in
 interactive mode:

 $ true | false | true | false
 $ echo [EMAIL PROTECTED]
 0


Works for me:

shlomi:~$ true | false | false | true
shlomi:~$ echo [EMAIL PROTECTED]
0 1 1 0

Maybe you execute some command after every prompt.

 Although it does work in non-interactive mode:

 $ echo $'true | false | true | false\necho [EMAIL PROTECTED]' | sh
 0 1 0 1


Wow, I wasn't aware of the $'' construct. I guess you learn something new
every day. :-)

 If you want a less fragile approach, Oded Arbel gave a good advice.


This approach is also dependent on the user shell being bash. I am using
this shell call from a Perl script. In any case, I eliminated the pipeline
from the command and now this is no longer relevant.

Thanks anyway.

Regards,

Shlomi Fish


--
Shlomi Fish[EMAIL PROTECTED]
Home Page: http://t2.technion.ac.il/~shlomif/

Writing a BitKeeper replacement is probably easier at this point than getting
its license changed.

Matt Mackall on OFTC.net #offtopic.


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-24 Thread Oleg Goldshmidt
Shlomi Fish [EMAIL PROTECTED] writes:

 On Fri, 24 Oct 2003, Beni Cherniavsky wrote:
 
  Shlomi Fish wrote on 2003-10-12:
 
   I want that if one of the (first) components of the pipeline exits with an
   error code, I'll know about it somehow. How?
  
  info bash --index PIPESTATUS
 
 
 Cool thanks.

Depending on your needs you may also use the -e option to the shell
(should work for most Bourne shell and csh descendants), the option
will make the shell exit if any of the commands in the pipeline fails.

$ true | false | true
$ echo $?
0
$ bash -e true | false | true
true | false | true: true | false | true: No such file or directory
$ echo $?
1

-- 
Oleg Goldshmidt | [EMAIL PROTECTED]

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-24 Thread Tzafrir Cohen
On Fri, Oct 24, 2003 at 10:47:22PM +0200, Oleg Goldshmidt wrote:
 Shlomi Fish [EMAIL PROTECTED] writes:
 
  On Fri, 24 Oct 2003, Beni Cherniavsky wrote:
  
   Shlomi Fish wrote on 2003-10-12:
  
I want that if one of the (first) components of the pipeline exits with an
error code, I'll know about it somehow. How?
   
   info bash --index PIPESTATUS
  
  
  Cool thanks.
 
 Depending on your needs you may also use the -e option to the shell
 (should work for most Bourne shell and csh descendants), the option
 will make the shell exit if any of the commands in the pipeline fails.
 
 $ true | false | true
 $ echo $?
 0
 $ bash -e true | false | true
 true | false | true: true | false | true: No such file or directory
 $ echo $?
 1

This is because you tried running a script from a file called
true | false | true

However:

$ set -e
$ true | false | true
$ echo $?
0

So setting that doesn't make an error from the middle of a pipe show.

-- 
Tzafrir Cohen   +---+
http://www.technion.ac.il/~tzafrir/ |vim is a mutt's best friend|
mailto:[EMAIL PROTECTED]   +---+

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Error code from a shell pipeline.

2003-10-12 Thread Shlomi Fish


$ make || echo hello
make: *** No targets specified and no makefile found.  Stop.
hello


But OTOH:


(make | echo) || echo hello

make: *** No targets specified and no makefile found.  Stop.


And also:


$ (echo | make) || echo hello
make: *** No targets specified and no makefile found.  Stop.
hello


I want that if one of the (first) components of the pipeline exits with an
error code, I'll know about it somehow. How?

Regards,

Shlomi Fish




--
Shlomi Fish[EMAIL PROTECTED]
Home Page: http://t2.technion.ac.il/~shlomif/

Writing a BitKeeper replacement is probably easier at this point than getting
its license changed.

Matt Mackall on OFTC.net #offtopic.


=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]



Re: Error code from a shell pipeline.

2003-10-12 Thread Oded Arbel
On Sunday 12 October 2003 18:38, Shlomi Fish wrote:
 (make | echo) || echo hello
 
 make: *** No targets specified and no makefile found.  Stop.

 I want that if one of the (first) components of the pipeline exits with an
 error code, I'll know about it somehow. How?

an erronouse exit code (actually, just not true) does not break the pipe. 
how about 
(make || echo oops 2 ) |  cat-or-something

-- 
Oded

::..
'I have been told that Introduction to Objectivist Epistemology was required 
reading at the Xerox PARC lab where OOP was invented, but this may be merely 
an urban legend.' 
-- Bryce Wilcox

=
To unsubscribe, send mail to [EMAIL PROTECTED] with
the word unsubscribe in the message body, e.g., run the command
echo unsubscribe | mail [EMAIL PROTECTED]