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: