Родительский скрипт продолжается, когда ребенок выходит с ненулевым кодом выхода

У меня есть сценарий, который вызывает другой скрипт. Когда дочерний скрипт терпит неудачу, я хотел бы, чтобы родительский сбой также не удался.

В дочернем скрипте child_1.sh меня есть что-то вроде этого:

 if [ $SOME_BAD_CONDITION ] ; then echo "Error message...." exit 1 fi 

У родителя у меня есть следующее:

 #!/bin/bash set -e #... bash ./child_1.sh echo "continuing to next step..." bash ./child_2.sh bash ./child_3.sh #... 

Я настроил свою среду таким образом, чтобы всегда $SOME_BAD_CONDITION , и сценарий завершается так, как ожидалось, и сообщение об ошибке печатает, но родительский скрипт продолжается: $SOME_BAD_CONDITION сообщение «continue …», и следующий скрипт начинает выполнение ,

Я думал, что set -e будет гарантировать, что мой родительский скрипт завершится с ошибкой, если какой-либо дочерний скрипт существует с ненулевым кодом выхода, но это, похоже, не происходит. Я не уверен, что я ошибся здесь …

версия bash: 4.2.25


ОБНОВИТЬ:

Я пробовал эхом $? :

 bash ./child_1.sh echo $? echo "continuing to next step..." 

Результат выглядит следующим образом:

 Сообщение об ошибке....
 0
 продолжая следующий шаг ...

Почему код выхода из ребенка не попадает в родительский?


ОТВЕТ: Исходный фрагмент кода был неполным. exit 1 находился внутри кодового блока, который был подключен к тройнику. Моя попытка опубликовать чистый, короткий пример кода проигнорировала это, потому что я не понимал, насколько это значимо (я все еще довольно новичок в bash-скриптах). Для получения более подробной информации см. Мой ответ.

  • как проверить, установлены ли оба параметра в bash?
  • Дата «1 месяц назад» не работает в AIX
  • Как повторить запрос пользователю в сценарии оболочки?
  • Какой интерпретатор оболочки запускает скрипт без shebang?
  • Как удалить первые n строк файла ascii с помощью команд оболочки?
  • Найти определенный файл в ближайшем предке текущего рабочего каталога
  • Что такое оболочка по умолчанию для .sh в AIX?
  • Как получить записи таблицы psql в сценарии оболочки?
  • 3 Solutions collect form web for “Родительский скрипт продолжается, когда ребенок выходит с ненулевым кодом выхода”

    Так как ваш дочерний процесс завершает работу с надлежащим нулевым / ненулевым кодом выхода, и если вы выполняете их последовательно, я бы сказал, что вы можете просто использовать оператор && :

     #!/bin/bash ./child_1.sh [[ $? -ne 0 ]] && exit # Exit if non-zero exit code ./child_2.sh ./child_3.sh ./child_4.sh exit 0 

    Здесь [[ $? -ne 0 ]] && exit [[ $? -ne 0 ]] && exit :

     if [ $? -ne 0 ]; then # If: last exit code is non-zero exit fi 

    Если вам нечего делать между вызовами, вы даже можете использовать …

     #!/bin/bash ./child_1.sh && ./child_2.sh && ./child_3.sh && ./child_4 exit $? 

    Оператор && действует как оператор короткого замыкания AND , а нулевой код выхода в значительной степени похож на true булево значение. Если в любой момент в цепочке сценарий завершается с ненулевым значением, то && будет терпеть неудачу, и сценарии с подпоследователями не должны вызываться.

    Таким образом, я, возможно, допустил ошибку, не размещая достаточно подробностей о дочернем скрипте – я упростил ее для этого вопроса, но, возможно, слишком много. Оператор exit был похоронен внутри кодового блока (между { и } ), который был запрограммирован на tee для ведения журнала:

     { #... if [ $SOME_BAD_CONDITION ] ; then exit 1 fi #... } | tee -a $LOGFILE echo "script ended at $date">>$LOGFILE 

    Из того, что я понимаю, у меня всегда был код возврата 0 из этого дочернего скрипта, потому что последнее echo возвращалось 0. Я провел некоторое исследование и обнаружил $ PIPESTATUS . Я смог использовать это, чтобы гарантировать, что когда мой скрипт попытается выйти с кодом выхода 1, он будет передан родительскому скрипту:

     { #... } | tee -a $LOGFILE EXIT_CODE=${PIPESTATUS[0]} echo "script ended at $date">>$LOGFILE exit $EXIT_CODE 

    В сочетании с предложением Джона у меня есть решение, которое, кажется, работает.

    Похоже, ваша проблема проистекает из того, как вы выбрасываете ошибку в своем дочернем скрипте.

    Из набора людей «если простая команда (см. SHELL GRAMMAR выше) выходит с ненулевым статусом. Оболочка не выходит, если неудавшаяся команда является частью списка команд сразу после некоторого времени или пока ключевое слово, часть теста в выражении if, в части списка && или ||, или если возвращаемое значение команды перевернулось через! "

    Вместо использования set -e используйте оператор trap и выдайте ошибку. (Если вам нужно использовать условный выход.

    См. http://mywiki.wooledge.org/BashFAQ/105

    Linux и Unix - лучшая ОС в мире.