automake-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

shell errexit and exit status (was: [PATCH] Internationalization tests:


From: Ralf Wildenhues
Subject: shell errexit and exit status (was: [PATCH] Internationalization tests: do not ignore failures.)
Date: Mon, 6 Sep 2010 20:26:38 +0200
User-agent: Mutt/1.5.20 (2010-04-22)

Hello Stefano,

* Stefano Lattarini wrote on Mon, Sep 06, 2010 at 05:06:23PM CEST:
> This patch fixes potential false negatives in the new tests.

> Internationalization tests: do not ignore failures.
> 
> Some tests used the idiom:
>   test $builddir = '.' || test ! -f posub/foo-bar.pot
> to check that a file is build in the source directory, not in
> the build directory.  But even when the `errexit' shell flag
> is active, the above does not abort the script even if the file
> `posub/foo-bar.pot' exists, since the failing `test' is in a
> `||' compound command.  Fix this problem by explicitly calling
> `Exit 1' where needed.

I'm not sure I understand this rationale.  The problem, as I see it, is
slightly different: with

  set -e
  false || false
  notreached

it is portable to assume that the last line in the script is not reached
any more.  That is, you can be sure that the script will exit
prematurely.

However, with this script:

  trap 'st=$?; exit $st' EXIT
  set -e
  true && false
  notreached

there is a problem with shells like Tru64 sh (and some others):
the false causes the shell to not execute the last line of the script
any more.  However, the value of $? at the time the EXIT trap is entered
is still that of the 'true' command, so 0.  Only after the exit trap is
finished, will the shell set $? to that of 'false'.  Problem is, the
shell doesn't ever get to that point, because the 'exit' within the trap
causes it to, well, exit before that, and with a status of $st which is
0.

This is why autoconf.texi has the following bits, and recommendation at
the end:

     Portable scripts should not use `set -e' if `trap' is used to
     install an exit handler.  This is because Tru64/OSF 5.1 `sh'
     sometimes enters the trap handler with the exit status of the
     command prior to the one that triggered the errexit handler:

          $ sh -ec 'trap '\''echo $?'\'' 0; false'
          0
          $ sh -c 'set -e; trap '\''echo $?'\'' 0; false'
          1

     Thus, when writing a script in M4sh, rather than trying to rely on
     `set -e', it is better to append `|| AS_EXIT' to any statement
     where it is desirable to abort on failure.

The equivalent to `|| AS_EXIT' in the Automake testsuite is `|| Exit 1'.

That also means, that we should probably be more cautious with removing
`|| Exit 1' instances from tests.

Or, here's a different idea: maybe we can somehow detect this shell
feature at run time.  In that case it is sufficient to just *not*
exit from within the trap (unless the trap code has caused another
failure status that should be reported).

Cheers,
Ralf



reply via email to

[Prev in Thread] Current Thread [Next in Thread]