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

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

В дочернем скрипте 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-скриптах). Для получения более подробной информации см. Мой ответ.

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

  • Обнаружение системы init с использованием оболочки
  • Мне нужно взять вывод команды и сделать ее именем файла, используя скрипт
  • Как установить пары фиксированного значения, вертикально ориентированные пары ключ-значение в файле CSV?
  • Как установка бита Setuid влияет на сценарии оболочки, которые запускаются при загрузке системы, до того, как произошел какой-либо логин?
  • массив сценариев оболочки для элементов файлов
  • Имеются ли у bash разные слабые правила цитирования для специальных переменных?
  • fdupes - удалять файлы после сравнения двух каталогов
  • Как установить переменную
  • Сценарий оболочки для объединения файлов свойств (sed / awk / comm / diff) для обновления rpm
  • Проверка наличия программного обеспечения в сеансе SSH
  • Скрипт пытается создать файлы, даже если им это не нужно?
  • Linux и Unix - лучшая ОС в мире.