`set -e` is for commands that fail and are not explicitly tested. You
are using an explicit test construct. See below for man page details and
a fix.
Kartik Agaram wrote on 12/03/16 03:23:
Synopsis: error with 'set -e' in /bin/sh
Category: system
Environment:
System : OpenBSD 5.9
Details : OpenBSD 5.9 (GENERIC) #1761: Fri Feb 26 01:15:04 MST 2016
[email protected]:/usr/src/sys/arch/amd64/compile/GENERIC
Architecture: OpenBSD.amd64
Machine : amd64
Description:
Bourne shell script with '-e' enabled sometimes runs past failing
commands
set:
-e | errexit Exit (after executing the ERR trap) as soon as
an error occurs or a command fails (i.e.
exits
with a non-zero status). This does not
apply to
commands whose exit status is explicitly
tested
by a shell construct such as if, until,
while,
or ! statements. For && or ||, only the
status
of the last command is tested.
How-To-Repeat:
I haven't been able to distill it down to a smaller testcase, so
please bear with me.
## initial setup
$ cat y0.c
int foo() {
return 34;
}
$ cat y1.c
int bar () {
return 35 /* some syntax error, say missing ';' */
}
$ touch y0.o y1.o
$ touch y0.c y1.c # .c files newer than .o files
$ cat build
#!/bin/sh
# stupid make replacement
set -e
for f in 0 1
do
echo checking y$f
[ y$f.c -nt y$f.o ] && gcc -c y$f.c
if [ y$f.c -nt y$f.o ]
then gcc -c y$f.c
fi
# echo # <=== line A disabled (see below)
done
echo ZZZ # should never get here since compiling y1.c errors
## first run
$ ./build
checking y0
checking y1
y1.c: In function 'main':
y1.c:5: error: expected ';' before '}' token
# no ZZZ printed; all is well
## second run
$ touch y0.o # y0.o newer than y0.c, y1.o older than y1.c
$ ./build
checking y0
checking y1
y1.c: In function 'main':
y1.c:5: error: expected ';' before '}' token
ZZZ # <=== whoops!
## third run
# uncomment line A in 'build' script
$ cat build
#!/bin/sh
set -e
for f in 0 1
do
echo checking y$f
[ y$f.c -nt y$f.o ] && gcc -c y$f.c
echo # <=== line A ENABLED
done
echo ZZZ
# Now ZZZ never prints regardless of relative modified times.