Subject: bin/36435: sh(1) bug with exit status of negated pipelines
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <giles.lean@pobox.com>
List: netbsd-bugs
Date: 06/04/2007 01:50:00
>Number:         36435
>Category:       bin
>Synopsis:       sh -c 'true && ! true | false' returns non-zero status
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jun 04 01:50:00 +0000 2007
>Originator:     Giles Lean
>Release:        NetBSD 4.0_BETA2
>Organization:
	
>Environment:
	
	
System: NetBSD amethyst.netherstone.net 4.0_BETA2 NetBSD 4.0_BETA2 (AMETHYST) #12: Tue May 29 08:01:56 EST 2007 unpriv@amethyst.netherstone.net:/usr/local/NetBSD/netbsd-4/obj/sys/arch/i386/compile/AMETHYST i386
Architecture: i386
Machine: i386
>Description:
    The following command has an exit status of one but should have zero:

        $ sh -c 'true && ! true | false'
        $ echo $?
        1

    In comparison, ksh returns zero:

        $ ksh -c 'true && ! true | false'
        $ echo $?
        0

    The Shell Command Language standard (from "The Open Group
    Base Specifications Issue 6", a.k.a. "IEEE Std 1003.1-2001")
    says:

    | Exit Status
    |
    | If the reserved word ! does not precede the pipeline, the
    | exit status shall be the exit status of the last command
    | specified in the pipeline. Otherwise, the exit status shall
    | be the logical NOT of the exit status of the last command.
    | That is, if the last command returns zero, the exit status
    | shall be 1; if the last command returns greater than zero,
    | the exit status shall be zero.

    I interpret this to mean that NetBSD's sh(1) is wrong, and
    that ksh(1) is right.  I tested on the (limited) platforms
    available to me with the following results:

    Problematic behaviour:      NetBSD  4.0_BETA2 sh(1)
			        FreeBSD 4.8       sh(1)

    Expected behaviour:         NetBSD  4.0_BETA2 ksh(1)
				FreeBSD 4.8       ksh(1)
				OS/X    10.4.9    sh(1), ksh(1), bash(1)

    For background and future searching, I found this while building
    git-1.5.2.  Some tests such as this one failed in t3700-add.sh:
  
        git-add . &&
        ! git-ls-files | grep "\\.ig"

    In this test the grep pattern should not matc, so the overall
    result should be grep's non-zero exit status negated by '!'.

>How-To-Repeat:
	
        $ sh -c 'true && ! true | false'
        $ echo $?
        1
>Fix:
	

>Unformatted: