Какие режимы выхода существуют в shell-скриптинге вообще и в Bash в частности?

команда update-modules устарела в течение некоторого времени. Эквивалент:

depmod -a

-121--290613-

Инструменты Fedora RPM очень умны в определении зависимостей времени выполнения самостоятельно, если только они не могут быть выведены из самих устанавливаемых файлов. Зависимости для построения вы узнаете сами. Возможно, Руководство Fedora по RPM полезно (я пользователь Fedora, и это лучший ресурс, который я знаю; возможно, ваш дистрибутив имеет более релевантную документацию для вашего использования). Fedora предлагает макет (1) , который создает чистую среду с помощью только встроенных инструментов, упомянутых для создания пакета. Это настоящая боль ( очень медленная, так как она по сути создает полную систему в хрооте, скачивая все для каждой сборки), но полезная финальная проверка.

2
03.10.2018, 16:38
3 ответа

an "exit" usually means voluntarily or at least successfully terminating

По крайней мере, текст POSIX, похоже, использует выход исключительно для добровольного завершения процесса, а не для уничтожения по внешней причине. (См., например.wait())Уничтожение процесса сигналом вряд ли считается успехом, поэтому любое успешное завершение должно в этом смысле быть "выходом".Хотя я ожидаю, что эти термины будут использоваться менее строго в неформальном употреблении.

Are there any other "exit modes" in shell scripting in general, and in Bash in particular?

Режим имеет особое техническое значение в некоторых контекстах (, например. chmod()), но я не могу придумать ни одного здесь, поэтому я не совсем уверен, о чем вы спрашиваете.

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

  1. Сценарий выполняется до конца сценария. Статус выхода скрипта соответствует статусу последней выполненной команды.
  2. Сценарий запускает встроенную командуexitбез аргументов. Опять же, статус выхода - это статус последней выполненной команды.
  3. Сценарий запускает команду exitс аргументом. Статус выхода — это значение аргумента.
  4. Скрипт ссылается на неустановленную переменную, пока действуютset -u/ set -o nounset. Статус выхода зависит от оболочки, но не равен нулю. (Кажется, что Bash использует 127.)(*)
  5. Сценарий запускает команду, которая завершается ошибкой, пока действуютset -e/ set -o errexit. Статус выхода соответствует неудачной команде.(Но см. BashFAQ 105 о проблемах с set -e.)
  6. В сценарии возникает синтаксическая ошибка. Статус выхода оболочки не равен нулю. (Кажется, что Bash использует 1.)(*)
  7. Сценарий получает сигнал , который приводит к его завершению. Не все сигналы вызывают завершение, и сигналы можно либо игнорировать, либо установить обработчик внутри скрипта с помощью встроенной командыtrap. Это также относится к экв. нажатие Ctrl -C , которое посылает сигнал SIGINT.(*)

С технической точки зрения, в случаях с 1 по 6 процесс оболочки , выполняющий сценарий, завершает работу (добровольно, т. е. процесс вызываетexit()). С другой стороны, с точки зрения самого скрипта , завершение из-за set -e, set -uили синтаксической ошибки вполне можно было бы назвать непроизвольным.Но сценарий оболочки — это не то же самое, что интерпретатор оболочки.

В пунктах с 1 по 3 принято использовать нулевой статус выхода для успешного завершения и отличное от -нулевое значение для неудач. Точное значение отличных от -нулевых значений зависит от утилиты. Некоторые могут использовать только ноль и единицу, некоторые могут использовать различные ненулевые статусы -для разных ситуаций. Например, grepиспользует 1, чтобы указать, что совпадений не найдено, а значения, превышающие 1, указывают на ошибки. Встроенные функции Bash также используют 2для обозначения таких ошибок, как недопустимые параметры. Использование аналогичного пользовательского может быть полезным, но вам необходимо задокументировать, что означает статус выхода вашего скрипта. Обратите внимание, что состояние выхода обычно ограничено 8 битами, поэтому диапазон составляет от 0до 255.

В случаях с 4 по 6 ситуация обычно рассматривается как своего рода сбой, поэтому статус выхода не -нулевой. В 7 нет статуса выхода. Вместо этого, когда процесс завершается из-за сигнала, системный вызов wait()указывает рассматриваемый сигнал. Если родительский процесс является оболочкой, он обычно представляет это со статусом выхода 128 + <signal number>, например. 143для дочернего объекта, завершенного с помощью SIGTERM.

(*В отличие от скриптов, интерактивные оболочки не закрываются из-за синтаксических ошибок или set -uили SIGINT.)

If I'm in the first shell-session it will usually cause the shell CLI window to close

Эмулятор терминала обычно закрывается, если запущенный им процесс завершается. Но это зависит от эмулятора терминала, а не от оболочки. Эмулятор терминала может решить оставить окно открытым, чтобы сообщить пользователю, что его программа завершена, и вы также можете запустить что-то другое, кроме оболочки, в эмуляторе терминала.

if I'm in some sub-session,execution will usually just move my user back to the previous session.

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

Bash сохраняет переменную SHLVL, которая увеличивается на единицу при каждом запуске Bash, так что в некотором смысле у него есть внутренняя идея вложенных оболочек. Но я не думаю, что фраза «сессия sub -» очень распространена, не говоря уже о любой такой нумерации. (Я думаю, что SHLVLинициализируется в 1.)

6
27.01.2020, 21:49

Я не уверен, правильно ли я понял вопрос, но вы, кажется, ищете разные способы завершения программы вместо выхода ?

  • вы можете запустить оболочку (или команду с помощью оболочки )выйти, как вы сказали (ex :Ваша интерактивная оболочка завершится, если она вызовет EoF. Любая оболочка также завершит работу, если у нее закончатся команды для запуска (конец скрипта )или если она встретит выход (ex :«выход 2» в оболочке, что приведет к выходу с кодом возврата 2)

  • вы можете получить «HUP», если родительская оболочка завершает работу и не выполняется «nohup» (или его вариант )для отключения вашего процесса от этой родительской оболочки

  • вы можете получить Ctrl -C

  • у вас могла закончиться память/процессор/что-то (fd?)

  • вы можете получить kill -9 или другое (сам скрипт может "убить -9 $$" себя таким образом, даже если это странно...)

  • ваш корпус может быть справа -от -стороны трубы, которая ломается, потому что левый конец резко обрывается

  • Бьюсь об заклад, таких случаев гораздо больше....

Каждый из них должен завершить программу/оболочку, и каждый немного по-своему (и вы можете перехватить некоторые из них, чтобы они сделали что-то перед выходом, или полностью предотвратить выход (для ctrl -C, для например, вы можете перехватить сигнал INT))

1
27.01.2020, 21:49

Существует гораздо больше кодов выхода, чем просто 0, 1 и 2. См.:

Размышляя о кодах выхода, вы должны помнить, что скрипты не всегда заканчиваются там, где вы можете их подозревать. Прежде чем они закончатся, они могут быть убиты сигналом или могут закончиться из-за незапланированного терминатора ввода из-за нажатия Ctrl-D , что приведет к неожиданным выходам. Таким образом, необходимо хорошее понимание и анализ сценариев, особенно тех, которые возвращают многочисленные коды.

1
27.01.2020, 21:49

Теги

Похожие вопросы