Код выхода в конце скрипта bash

22

Я запутался в значении кода завершения в конце скрипта bash: я знаю, что код выхода 0 означает, что он успешно завершился, и что есть еще много кодов выхода (127, если я не ошибаюсь?)

Мой вопрос заключается в том, что, когда код завершения 0 отображается в конце скрипта, он принудительно устанавливает код выхода как 0, даже если скрипт не выполнен или имеет другое значение?

Разоренный
источник
2
Если сценарий заканчивается на exit 0, он завершится с кодом выхода 0 независимо от того, что происходит в сценарии.
Hatclock
@Hatclock, почему вы не опубликовали свой ответ в виде обещанного ответа? в качестве комментария я не могу пометить это, и я не думаю, что вы получаете фальшивые очки в Интернете за ответы (верно?) Просто мысль ... (спасибо за быстрый ответ)
Busted
1
Я нахожусь на вокзале по телефону, мне не очень нравится набирать текст на телефоне. У ilkkachu, похоже, хороший ответ!
Hatclock
2
@ Хэтчлок Нет, совсем нет. Если скрипт заканчивается на exit 0, он завершится с кодом 0, только если была выполнена эта последняя инструкция. Единственное влияние exit 0в конце скрипта - вернуть 0 вместо статуса из предыдущей инструкции.
Жиль "ТАК ... перестать быть злым"

Ответы:

22

Встроенная команда exitвыходит из оболочки (из ссылки Bash ):

exit [n]
Выйдите из оболочки, вернув статус n родителю оболочки. Если n опущено, статус выхода соответствует статусу последней выполненной команды. Любая ловушка на EXIT выполняется перед завершением оболочки.

Запуск до конца файла также завершается, возвращая код возврата последней команды, так что да, финал exit 0заставит скрипт завершиться с успешным состоянием независимо от состояния выхода предыдущих команд. (То есть, если сценарий дошел до финала exit.) В конце сценария вы также можете использовать trueили :для получения кода выхода, равного нулю.

Конечно, чаще вы будете использовать exitизнутри, ifчтобы закончить сценарий в середине.

Они должны вывести 1 ( $?содержит код завершения, возвращенный предыдущей командой):

sh -c "false" ; echo $?
sh -c "false; exit" ; echo $?

Хотя это должно вывести 0:

sh -c "false; exit 0" ; echo $?

Я не уверен, имеет ли exitсмысл сценарий «сбой» при выполнении сценария , поскольку некоторые команды, запускаемые сценарием, вполне могут потерпеть неудачу, но сам сценарий может быть успешным. Это зависит от автора сценария, чтобы решить, что является успехом, а что нет.

Кроме того, стандартный диапазон для кодов выхода - 0..255. Коды выше 127 используются оболочкой для обозначения процесса, завершенного сигналом, но они могут быть возвращены обычным способом. waitСистемный вызов фактически возвращает более широкое значение, с остальными , содержащими битами состояния , установленных в операционной системе.

ilkkachu
источник
Круто, я не знал о нумерации 8-битных кодов выхода. Благодарность!
Вылетел
Обратите внимание, что когда процесс завершается, он не завершается с кодом выхода> 127. Просто в некоторых случаях для некоторых оболочек устанавливается $?значение 128 + signum. См. Код завершения по умолчанию, когда процесс завершается? для деталей.
Стефан Шазелас
exit 0вернет только 0, если выход выполнен. (это может выйти по другому маршруту).
Ctrl-Alt-Delor
18

0 означает успех, положительные целые означают неудачу. Существует 255 различных кодов ошибок, но значения 126 и выше зарезервированы, чтобы указать, что программа не может запуститься (126 или 127) или была уничтожена сигналом (129 и выше). См. Код завершения по умолчанию, когда процесс завершается? и какие значения возврата / выхода я могу использовать в функциях / скриптах bash? за дополнительной информацией.

Состояние завершения сценария оболочки - это состояние завершения последней команды, выполненной сценарием. Так например

#!/bin/sh
somecommand

возвращает статус выхода somecommand, тогда как

#!/bin/sh
somecommand
exit 0

возвращает 0 независимо от того, что somecommandвернул. Этот второй сценарий также может быть написан

#!/bin/sh
somecommand
true

Помещение exit 0в конец скрипта не обязательно приводит к тому, что он возвращает 0. Это только возвращает 0, когда достигнут конец скрипта. Например, следующий скрипт всегда возвращает 3:

#!/bin/sh
exit 3
exit 0

Следующий скрипт также всегда возвращает код ошибки, в дополнение к отображению сообщения о синтаксической ошибке:

#!/bin/sh
}
exit 0

Следующий скрипт возвращает 1 или 0 в зависимости от первого аргумента:

#!/bin/sh
if [ "$1" = "foo" ]; then
  exit 1
fi
exit 0

Следующий скрипт возвращает статус somecommand, так как set -eвызывает somecommandсбой скрипта в случае сбоя:

#!/bin/sh
set -e
somecommand
exit 0
Жиль "ТАК - перестань быть злым"
источник