По большей части я предпочитаю, чтобы мои сценарии заканчивались при возникновении непредвиденной ошибки, и поэтому обычно они запускаются с set -e -u -E -o pipefail
.
Однако иногда мне нужно захватить код завершения одного вызова и не завершается. Это приводит к таким конструкциям, как
# (1) Verbose. Breaks when moved between scripts
# with different global -e setting.
set +e
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
exitCode=$?
set -e
# (2) Verbose.
if COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
then exitCode=$?
else exitCode=$?
fi
# (3)
exitCode=0
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES \
|| exitCode=$?
# (4) Brittle, must not mix up order of && and ||
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES \
&& exitCode=$? || exitCode=$?
# (5), doesn't work with `set -o pipefail`
COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES | cat
exitCode=$PIPESTATUS
# (6) Requires maintaining a function across scripts.
captureExitCode COMMAND WITH A LOT OF ARGUMENTS \
| AND MAYBE EVEN PIPES \
| MAYBE OVER MANY LINES
# where
captureExitCode() {
# any of the above constructs with "$@" as command
}
. Все они либо многословны, либо несколько сложны для визуального анализа, особенно если COMMAND ...
- команда многострочного трубопровода. По крайней мере, они плохо сообщают о своих намерениях. В случае captureExitCode
функция должна воспроизводиться в разных сценариях.
Есть ли менее подробный встроенный идиом для захвата кода выхода?