Subject: bin/9184: sh exit status
To: None <gnats-bugs@gnats.netbsd.org>
From: Patrick Welche <prlw1@cam.ac.uk>
List: netbsd-bugs
Date: 01/13/2000 11:04:07
>Number:         9184
>Category:       bin
>Synopsis:       ! cmd | cmd doesn't "logical not"
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 13 11:03:00 2000
>Last-Modified:
>Originator:     Patrick Welche
>Organization:
	
>Release:        9 January 2000
>Environment:
System: NetBSD 1.4P i386

>Description:
According to sh(1):
     The format for a pipeline is:

           [!] command1 [| command2 ...]
...
     If the reserved word ! does not precede the pipeline, the exit status is
     the exit status of the last command specified in the pipeline.  Other-
     wise, the exit status is the logical NOT of the exit status of the last
     command.  That is, if the last command returns zero, the exit status is
     1; if the last command returns greater than zero, the exit status is ze-
     ro.

However the "!" seems to be ignored, and I got stung by it using postgresql's
initdb script, so this behaviour is assumed to exist.
>How-To-Repeat:
eg: the script

#!/bin/sh
echo "abc" | grep "a"
echo $?
! echo "abc" | grep "a"
echo $?
echo "zzz" | grep "a"
echo $?
! echo "zzz" | grep "a"
echo $?

returns:

abc
0
abc
0
1
1

compared to the correct solution as returned by /bin/ksh:

abc
0
abc
1
1
0

>Fix:
I don't know! Most useful line seems to be

        case NNOT:
                evaltree(n->nnot.com, EV_TESTED);
                exitstatus = !exitstatus;
                break;

in eval.c, but I don't see where the '!' bit is implemented (apart from $!
re background pid) - parser.c:495?
>Audit-Trail:
>Unformatted: