Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 27 Dec 2011 17:59:59 -0500
From:      Maxim Khitrov <max@mxcrypt.com>
To:        Devin Teske <devin.teske@fisglobal.com>
Cc:        FreeBSD <freebsd-questions@freebsd.org>
Subject:   Re: Unexpected sh behavior with EXIT trap and errexit
Message-ID:  <CAJcQMWdZNzdQ2sER6EXH0d5hTE3Q70PUQ7tU5x-ZLcrfC3jFbQ@mail.gmail.com>
In-Reply-To: <029f01ccc4df$9cca8190$d65f84b0$@fisglobal.com>
References:  <CAJcQMWcR9dUqv5fUifEk7r0qN55RJvTnoX2Os3NQqHaghtZ9QA@mail.gmail.com> <029f01ccc4df$9cca8190$d65f84b0$@fisglobal.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Dec 27, 2011 at 4:36 PM, Devin Teske <devin.teske@fisglobal.com> wr=
ote:
>> -----Original Message-----
>> From: owner-freebsd-questions@freebsd.org [mailto:owner-freebsd-
>> questions@freebsd.org] On Behalf Of Maxim Khitrov
>> Sent: Tuesday, December 27, 2011 12:25 PM
>> To: FreeBSD
>> Subject: Unexpected sh behavior with EXIT trap and errexit
>>
>> Can anyone explain this behavior (FreeBSD 9.0-RC3 amd64):
>>
>> Script:
>> ----
>> #!/bin/sh
>>
>> cleanup()
>> {
>> =C2=A0 =C2=A0 echo 'first'
>> =C2=A0 =C2=A0 echo 'second'
>> }
>>
>> fail() { return 42; }
>>
>> trap cleanup EXIT
>> set -o errexit
>> fail
>> ----
>>
>> Output:
>> ----
>> first
>> ----
>>
>
> If you change to:
>
> fail() { false; }
>
> Then the outcome is what you expect (both lines come out).

It seems that any command other than return, built-in or external,
works as expected.

> ASIDE: It appears that it's nothing to do with echo, stdout, or anything =
other than the fact that only the first command of the cleanup routine is c=
alled.

Correct, I used echo just for the example. I also tried 'set +o
errexit' as the first line of cleanup() to see if that would allow
execution to continue. Nope.

> From sh(1) regarding errexit:
>
> "If a shell function is executed and its exit status is explicitly tested=
, all commands of the function are considered to be tested as well."
>
> The exact meaning of which escapes me at the moment, but I'm lead to beli=
eve that this explanation somehow plays a role in what we're witnessing wit=
h your sample.

I don't know if this is related, but it means that errexit should not
cause the following code to terminate (and it doesn't):

dosomething()
{
    echo 'here'
    false
    echo 'still here'
}

set -o errexit
dosomething || true
echo 'all is well'

> It may be a bug, it may not. What's interesting in the sample is that the=
 "return 42" is a valid command that succeeds while the function itself doe=
s not.
>
> HTH,
> Devin
>
>
>> Now comment out 'set -o errexit', replace 'fail' with 'fail || exit'
>> (which should be equivalent to using errexit), and run again.
>>
>> Output:
>> ----
>> first
>> second
>> ----
>>
>> Am I doing something stupid or is this a bug? Bash prints out the same
>> (second) output for both versions of the code.
>>
>> - Max



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAJcQMWdZNzdQ2sER6EXH0d5hTE3Q70PUQ7tU5x-ZLcrfC3jFbQ>