- What is the meaning of exit 0, exit 1, and exit 2 in a bash script?
- 3 Answers 3
- Команда exit в Bash и коды выхода
- Статус выхода
- Команда exit
- Примеры
- Выводы
- Как использовать коды завершения в Bash-скриптах
- Что такое коды завершения
- Что происходит, когда коды завершения не определены
- Как использовать коды завершения в Bash-скриптах
- Проверяем коды завершения
- Создаём собственный код завершения
- Как использовать коды завершения в командной строке
- Дополнительные коды завершения
What is the meaning of exit 0, exit 1, and exit 2 in a bash script?
A bash script is like a movie theater, there are different exists. The exit statements mark the location of the exits for the bash interpreter. When the script is fired, the interpreter is required to run until the nearest exit.
1) You accepted an answer right after posting the question. Give it 24 hours to wait for even better answers. 2) The accepted answer is wrong and misleading. The correct answer is «there is no default meaning for the exit codes (beyond 0 = success); you as script developer define the semantics». 3) If you made that script, why did you add the exit commands (all of which are logically superfluous or could collapse to «exit 1» since you use if-else anyway).
3 Answers 3
Exit code 0 Success Exit code 1 General errors, Miscellaneous errors, such as "divide by zero" and other impermissible operations Exit code 2 Misuse of shell builtins (according to Bash documentation) Example: empty_function() <>
Caveat: Using the proper exit code is not a requirement and is not enforced by the shell. Developers can ignore the guidance if they think it wise.
Also, while the linked source, the Advanced Bash Scripting Guide, claims to show «Reserved Exit Codes» (emphasis in original), that claim is both uncited and entirely false.
Using exit and a number is a handy way of signalling the outcome of your script. It mimics the way that bash commands output a return code. With bash commands the return code 0 usually means that everything executed successfully without errors. exit also makes your script stop execution at that point and return to the command line.
Any return code greater than 0 indicates an error of some sort, though sometimes the error isn’t critical, for each command it should be possible to find some documentation that tells you what each return code means.
You can get the return code of the last bash command by using the shell variable $? like so:
$ echo "something" something $ echo $? 0 $ cp cp: missing file operand Try 'cp --help' for more information. $ echo $? 1
When you use this in a script, you can query the return code in the same way when it’s done executing. So you’ll see that having:
Is sort of meaningless, as you can never reach the exit 0 part.
All by itself, exit implies an exit value of zero, or successful completion of your script. You do not have to add the zero argument to the exit command to indicate successful completion. Your script may (or probably will) exit successfully although it tests for an erroneous condition. In this case you specifically want it to exit with the error (or 1) condition.
echo -e "Enter numbers 1-4" \c" read NUM case $NUM in 1) echo "one";; 2) echo "two";; 3) echo "three";; 4) echo "four";; *) echo "invalid answer" exit 1;; esac
The exit command in the last line does not have to be there at all. It could be called with the zero or not called at all. Without specifying the 1 argument to the exit command the answer in all these cases to the echo $? would be zero.
However by specifying the 1 argument to the exit command the response to the echo $? would be 1. So use the 1 argument to the exit command when you want to specify that the script has exited with an error condition.
Команда exit в Bash и коды выхода
Часто при написании сценариев Bash вам необходимо завершить сценарий при выполнении определенного условия или выполнить действие на основе кода выхода команды.
В этой статье мы рассмотрим встроенную команду exit Bash и статусы выхода выполненных команд.
Статус выхода
Каждая команда оболочки возвращает код выхода, когда она завершается успешно или безуспешно.
По соглашению нулевой код выхода указывает, что команда завершилась успешно, а ненулевое значение означает, что произошла ошибка.
Специальная переменная $? возвращает статус выхода последней выполненной команды:
Команда date завершена успешно, код выхода равен нулю:
Если вы попытаетесь запустить ls в несуществующем каталоге, код выхода будет отличным от нуля:
ls /nonexisting_dir &> /dev/null
echo $?
Код состояния можно использовать для выяснения причины сбоя команды. На странице руководства каждой команды содержится информация о кодах выхода.
При выполнении многокомандного конвейера статус выхода конвейера соответствует состоянию последней команды:
sudo tcpdump -n -l | tee file.out
echo $?
В приведенном выше примере echo $? напечатает код выхода команды tee .
Команда exit
Команда exit закрывает оболочку со статусом N Он имеет следующий синтаксис:
Если N не задано, код состояния выхода — это код последней выполненной команды.
При использовании в сценариях оболочки значение, указанное в качестве аргумента команды exit возвращается оболочке как код выхода.
Примеры
Статус выхода команд может использоваться в условных командах, таких как if . В следующем примере grep завершит работу с нулем (что означает истину в сценариях оболочки), если «строка поиска» найдена в filename :
if grep -q "search-string" filename then echo "String found." else echo "String not found." fi
При запуске списка команд, разделенных && (И) или || (ИЛИ), статус выхода команды определяет, будет ли выполнена следующая команда в списке. Здесь команда mkdir будет выполнена, только если cd вернет ноль:
cd /opt/code && mkdir project
Если сценарий завершается exit без указания параметра, код выхода из сценария — это код последней команды, выполненной в сценарии.
#!/bin/bash echo "doing stuff. " exit
Использование только exit — это то же самое, что и exit $? или пропуская exit .
Вот пример, показывающий, как завершить сценарий, если он запущен пользователем без полномочий root:
#!/bin/bash if [[ "$(whoami)" != root ]]; then echo "Only user root can run this script." exit 1 fi echo "doing stuff. " exit 0
Если вы запустите сценарий как root, код выхода будет нулевым. В противном случае скрипт выйдет со статусом 1 .
Выводы
Каждая команда оболочки возвращает код выхода при завершении. Команда exit используется для выхода из оболочки с заданным статусом.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Как использовать коды завершения в Bash-скриптах
Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.
Что такое коды завершения
В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.
Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.
Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.
Что происходит, когда коды завершения не определены
В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.
#!/bin/bash touch /root/test echo created file
Этот скрипт запускает команды touch и echo . Если запустить этот скрипт без прав суперпользователя, команда touch не выполнится. В этот момент мы хотели бы получить информацию об ошибке с помощью соответствующего кода завершения. Чтобы проверить код выхода, достаточно ввести в командную строку специальную переменную $? . Она печатает код возврата последней запущенной команды.
Как видно, после запуска команды ./tmp.sh получаем код завершения 0 . Этот код говорит об успешном выполнении команды, хотя на самом деле команда не выполнилась. Скрипт из примера выше исполняет две команды: touch и echo . Поскольку код завершения не определён, получаем код выхода последней запущенной команды. Это команда echo , которая успешно выполнилась.
Если убрать из скрипта команду echo , можно получить код завершения команды touch .
Поскольку touch в данном случае — последняя запущенная команда, и она не выполнилась, получаем код возврата 1 .
Как использовать коды завершения в Bash-скриптах
Удаление из скрипта команды echo позволило нам получить код завершения. Что делать, если нужно сделать разные действия в случае успешного и неуспешного выполнения команды touch ? Речь идёт о печати stdout в случае успеха и stderr в случае неуспеха.
Проверяем коды завершения
Выше мы пользовались специальной переменной $? , чтобы получить код завершения скрипта. Также с помощью этой переменной можно проверить, выполнилась ли команда touch успешно.
#!/bin/bash touch /root/test 2> /dev/null if [ $? -eq 0 ] then echo "Successfully created file" else echo "Could not create file" >&2 fi
После рефакторинга скрипта получаем такое поведение:
- Если команда touch выполняется с кодом 0 , скрипт с помощью echo сообщает об успешно созданном файле.
- Если команда touch выполняется с другим кодом, скрипт сообщает, что не смог создать файл.
Любой код завершения кроме 0 значит неудачную попытку создать файл. Скрипт с помощью echo отправляет сообщение о неудаче в stderr .
Создаём собственный код завершения
Наш скрипт уже сообщает об ошибке, если команда touch выполняется с ошибкой. Но в случае успешного выполнения команды мы всё также получаем код 0 .
Поскольку скрипт завершился с ошибкой, было бы не очень хорошей идеей передавать код успешного завершения в другую программу, которая использует этот скрипт. Чтобы добавить собственный код завершения, можно воспользоваться командой exit .
#!/bin/bash touch /root/test 2> /dev/null if [ $? -eq 0 ] then echo "Successfully created file" exit 0 else echo "Could not create file" >&2 exit 1 fi
Теперь в случае успешного выполнения команды touch скрипт с помощью echo сообщает об успехе и завершается с кодом 0 . В противном случае скрипт печатает сообщение об ошибке при попытке создать файл и завершается с кодом 1 .
Как использовать коды завершения в командной строке
Скрипт уже умеет сообщать пользователям и программам об успешном или неуспешном выполнении. Теперь его можно использовать с другими инструментами администрирования или однострочниками командной строки.
В примере выше && используется для обозначения «и», а || для обозначения «или». В данном случае команда выполняет скрипт ./tmp.sh , а затем выполняет echo «bam» , если код завершения 0 . Если код завершения 1 , выполняется следующая команда в круглых скобках. Как видно, в скобках для группировки команд снова используются && и || .
Скрипт использует коды завершения, чтобы понять, была ли команда успешно выполнена. Если коды завершения используются некорректно, пользователь скрипта может получить неожиданные результаты при неудачном выполнении команды.
Дополнительные коды завершения
Команда exit принимает числа от 0 до 255 . В большинстве случаев можно обойтись кодами 0 и 1 . Однако есть зарезервированные коды, которые обозначают конкретные ошибки. Список зарезервированных кодов можно посмотреть в документации.
Адаптированный перевод статьи Understanding Exit Codes and how to use them in bash scripts by Benjamin Cane. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.