2

I'm currently working on some init scripts that should both use set -e and confirm to the Linux Standard Base core specification. Now those two don't really work together:

Since due to the set -e the first command that fails causes the scripts to exit with the return value of the failed command I cannot set the exit status of the script to something LSB conformant for commands that fail with LSB incompatible return values. I could unset -e before each such command, but that's quite a hassle and in that case I'd actually rather not use set -e at all?

I guess another way to achieve the same result as with unset -e would be to do something like

returns_1() { return 1; }

...

cmd_that_fails_with_non_LSB_return_values || returns_1

but that seems quite bulky as well and I'd again have to check each and every command's possible return values.

Is there a way to set the error code returned by the script when it is terminated due to set -e to a fixed value so it would return 1 (i.e. LSB general/unspecified error) no mather what return value the failed command had? Should I not bother with LSB conformant return codes and/or set -e? (this will probably turn into a discussion about the merrits of set -e anyway judging from the amount of search results you get for that)

Small code snippet to illustrate the problem:

#!/bin/bash
# init script for service foo
set -e

start() {
  echo "bar"
  cmd_fails_with_return_code_3 # script exits with return code 3, not LSB conformant
  echo "baz"
}

...

case "$1" in
  start)
    start
    ;;
  ...
esac
a.peganz
  • 318
  • 1
  • 4
  • 11
  • 2
    I think the `command || exit 1` construct is reasonable. Of course, you could execute your script in a child process and only check the return value of that but I don't like the idea. – 5gon12eder Sep 17 '14 at 14:15

2 Answers2

6

From the man page, it appears you can set a trap on ERR:

A trap on  ERR, if set, is executed before the shell exits. 

I haven't tried this but this would mean something like this might help you:

trap "exit 1" ERR

Be sure to read the man page for other useful options such as -E to inherit the ERR trap in subshells.

geert3
  • 7,086
  • 1
  • 33
  • 49
3

You basically have it nailed, although the returns function is superfluous.

cmd_that_fails_with_non_LSB_return_values || exit 1

More typically, you would actually somehow handle the error, if only just to report what happened.

die () {
    echo "$0: $@" >&2
    exit 1
}
:
cmd_that_fails_with_non_LSB_return_values ||
    die "Long command with underscores failed; aborting"

Philosophically, I suppose the purpose of set -e is mainly to "gently remind" (that is, force) you to handle all possible error conditions.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • I guess this is the best solution for me. Not too much additional typing and more flexibility and control than a subshell or trap. Plus, I don't have to learn the concepts behind trap :D Thanks! – a.peganz Sep 18 '14 at 06:27