Баш: как поймать причину ошибки?


Я хочу поймать ошибку внутри скрипта оболочки, а затем создать некоторый отчет о причине ошибки:

trap 'error_handler' ERR

В моей функции error_handler я хочу указать причину, по которой был пойман сигнал ERR (например, "отказано в разрешении", "не удается найти удаленный хост" и т. д.).

Возможно ли это?

2 4

2 ответа:

Не совсем. Единственная информация, которая гарантированно доступна в обработчике ошибок, - это состояние выхода процесса, запустившего ERR, в $?. Вы даже не знаете ни имени процесса, ни его идентификатора. Я думаю, что обработчик ошибок предназначен для очистки общего назначения перед выходом из сценария, поэтому не имеет значения, какой процесс имел ненулевой статус выхода или почему.

Вам лучше сообщать об ошибках или иметь дело с ними сразу же, когда они случаются., вот так:

rm foo || { echo "File removal failed"; }

Обратите внимание, что большинство команд печатают свои собственные уведомления о сбое до стандартной ошибки.

Я не думаю, что обработчик ловушки ошибок получает какую-либо информацию о точной ошибке, которая вызвала его запуск. Вы можете получить код выхода из неудачной команды, но к моменту запуска ловушки вы даже не знаете, какая команда потерпела неудачу.

Вы можете попробовать написать простую программу на языке Си, чтобы извлечь последнюю системную ошибку с помощью perror или чего-то подобного.

... Обновление: это не работает; в ретроспективе, по очевидным причинам. Я оставлю это здесь для будущих поколений, чтобы узнать. /- :

vnix$ cat perror.c
#include <stdio.h>
#include <errno.h>

int main (int argc, char **argv)
{
  perror("");
}

vnix$ gcc perror.c

vnix$ touch /fnord
touch: cannot touch `/fnord': Permission denied

vnix$ ./a.out
Success