выйти сразу после сбоя и вывести сообщение об ошибке перед выходом из оболочки

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

set -e
command A || (echo "A failed";exit 1)
command B || (echo "B failed";exit 1)
if Condition C;
then
   command D || (echo "D failed";exit 1)

он делает то, что я хочу. Если не удалось выполнить команду A/B/D, выведите мне правильное сообщение и выйдите. Я знаю, что () означает подоболочку, и в подоболочке она повторяет что-то, а затем возвращает false в подоболочке (выход 1), поэтому это «ложь || ложь» и, таким образом, выход в основной оболочке. Мой вопрос в том, что это то же самое, что:

#set -e
    command A || { echo "A failed";exit 1; }
    command B || { echo "B failed";exit 1; }
    if Condition C;
    then
       command D || {echo "D failed";exit 1; }

если нет, то какая разница? В моем тесте они ведут себя одинаково.


person code3    schedule 20.05.2020    source источник


Ответы (1)


Во второй версии exit 1 выходит из исходной оболочки, а не из подоболочки. Вот почему вам не нужно set -e, чтобы скрипт закрылся, когда это произойдет.

Вы можете получить эквивалент первой оболочки следующим образом:

set -e
command A || { echo "A failed";false; }
command B || { echo "B failed";false; }
if Condition C;
then
   command D || {echo "D failed";false; }

false завершает работу с ненулевым статусом, который вызывает set -e выход из оболочки.

person Barmar    schedule 20.05.2020
comment
Благодарю. какова наилучшая практика в этом случае? С моей точки зрения, я думаю, что все эти три подхода одинаковы, верно? - person code3; 20.05.2020
comment
для достижения моей цели - person code3; 20.05.2020
comment
Явное обычно лучше. Используйте exit, если вы хотите выйти из скрипта в определенном месте. set -e следует использовать, если вы хотите выйти после непредвиденных ошибок. Если вы хотите что-то регистрировать при выходе, используйте trap EXIT или trap ERR. - person Barmar; 20.05.2020
comment
что, если я захочу выйти после непредвиденных ошибок? (потому что это важный скрипт, и мы хотели бы быть встревожены, если что-то не так). Я думаю, что мне все равно следует использовать set -e, но вместо использования || (echo xxx;exit 1), я могу использовать TRAP errorfun EXIT для регистрации перед выходом? - person code3; 20.05.2020
comment
Было бы замечательно, если бы set -e просто завершал работу после непредвиденных ошибок, но реальность значительно уродливее - person that other guy; 20.05.2020
comment
@thatotherguy Да, я упрощал, классифицируя все ошибки, которые вы явно проверяете с помощью if и ||, как и ожидалось. - person Barmar; 20.05.2020