Используйте прерывание!
tempfiles=( )
cleanup() {
rm -f "${tempfiles[@]}"
}
trap cleanup 0
error() {
local parent_lineno="$1"
local message="$2"
local code="${3:-1}"
if [[ -n "$message" ]] ; then
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}"
else
echo "Error on or near line ${parent_lineno}; exiting with status ${code}"
fi
exit "${code}"
}
trap 'error ${LINENO}' ERR
... тогда, каждый раз, когда Вы создаете временный файл:
temp_foo="$(mktemp -t foobar.XXXXXX)"
tempfiles+=( "$temp_foo" )
и $temp_foo
будет удален на выходе, и текущий номер строки будет распечатан. (set -e
аналогично даст Вам поведение выхода на ошибке, , хотя оно идет с серьезными протестами и ослабляет предсказуемость и мобильность кода).
можно или позволить вызову прерывания error
для Вас (в этом случае, он использует код выхода по умолчанию 1 и никакое сообщение), или назовите его сами и обеспечьте явные значения; например:
error ${LINENO} "the foobar failed" 2
выйдет с состоянием 2 и даст явное сообщение.
Я использовал
die() {
echo $1
kill $
}
прежде; я думаю, потому что 'выход' перестал работать для меня по некоторым причинам. Вышеупомянутые значения по умолчанию походят на хорошую идею, все же.
Это - прекрасное решение. Я просто хотел добавить
set -e
как элементарный ошибочный механизм. Это сразу остановит Ваш сценарий, если простая команда перестанет работать. Я думаю, что это должно было быть поведением по умолчанию: так как такие ошибки почти всегда показывают что-то неожиданное, это не 'действительно нормально', чтобы продолжать выполнять следующие команды.
Другое соображение является кодом выхода для возврата. Просто" 1
" является довольно стандартным, хотя существует горстка зарезервированные коды выхода, которые колотят себя использование , и та же самая страница утверждает, что пользовательские коды должны быть в диапазоне 64-113 для приспосабливания стандартам C/C++.
Вы могли бы также рассмотреть подход битовый вектора что mount
использование для его кодов выхода:
0 success
1 incorrect invocation or permissions
2 system error (out of memory, cannot fork, no more loop devices)
4 internal mount bug or missing nfs support in mount
8 user interrupt
16 problems writing or locking /etc/mtab
32 mount failure
64 some mount succeeded
OR
- луг коды вместе позволяет Вашему сценарию сигнализировать о нескольких одновременных ошибках.
Я предпочитаю звонить по очень легкому телефону. Так что я использую что-то, что кажется немного сложным, но простым в использовании. Обычно я просто копирую и вставляю приведенный ниже код в свои скрипты. За кодом следует пояснение.
#This function is used to cleanly exit any script. It does this displaying a
# given error message, and exiting with an error code.
function error_exit {
echo
echo "$@"
exit 1
}
#Trap the killer signals so that we can exit with a good message.
trap "error_exit 'Received signal SIGHUP'" SIGHUP
trap "error_exit 'Received signal SIGINT'" SIGINT
trap "error_exit 'Received signal SIGTERM'" SIGTERM
#Alias the function so that it will print a message with the following format:
#prog-name(@line#): message
#We have to explicitly allow aliases, we do this because they make calling the
#function much easier (see example).
shopt -s expand_aliases
alias die='error_exit "Error ${0}(@`echo $(( $LINENO - 1 ))`):"'
Я обычно помещаю вызов функции очистки вместе с функцией error_exit, но это варьируется от сценария к сценарию, поэтому я оставил это. Ловушки улавливают общие завершающие сигналы и следят за тем, чтобы все было очищено. Псевдоним - вот что делает настоящую магию. Люблю все проверять на отказ. В общем, я называю программы "если!" заявление типа. Вычитая 1 из номера строки, псевдоним скажет мне, где произошел сбой. К тому же это очень просто вызвать, и это в значительной степени доказательство идиота. Ниже приведен пример (просто замените / bin / false на то, что вы собираетесь вызвать).
#This is an example useage, it will print out
#Error prog-name (@1): Who knew false is false.
if ! /bin/false ; then
die "Who knew false is false."
fi
Эквивалентная альтернатива "set -e" -
set -o errexit
Это делает значение флага несколько понятнее, чем просто "-e".
Случайное добавление: для временного отключения флага , и вернуться к значению по умолчанию (продолжение выполнения независимо от кодов выхода), просто используйте
set +e
echo "commands run here returning non-zero exit codes will not cause the entire script to fail"
echo "false returns 1 as an exit code"
false
set -e
. Это исключает надлежащую обработку ошибок, упомянутую в других ответах, но выполняется быстро и эффективно (как и bash).