- Команда exit в Bash и коды выхода
- Статус выхода
- Команда exit
- Примеры
- Выводы
- Linux and Unix exit code tutorial with examples
- What is an exit code in the UNIX or Linux shell? ¶
- How to get the exit code of a command ¶
- How to use exit codes in scripts ¶
- How to set an exit code ¶
- What exit code should I use? ¶
- How to suppress exit statuses ¶
- Further reading ¶
- Tags
- See Also
- How to use Linux shell command exit codes
- What the return codes mean
- Customize the return code
- Training & certification
- Test the return code with a shell script
- Test the return code with an Ansible playbook
Команда 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 используется для выхода из оболочки с заданным статусом.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Linux and Unix exit code tutorial with examples
Tutorial on using exit codes from Linux or UNIX commands. Examples of how to get the exit code of a command, how to set the exit code and how to suppress exit codes.
- August 7, 2016
- Updated May 24, 2023
What is an exit code in the UNIX or Linux shell? ¶
An exit code, or sometimes known as a return code, is the code returned to a parent process by an executable. On POSIX systems the standard exit code is 0 for success and any number from 1 to 255 for anything else.
Exit codes can be interpreted by machine scripts to adapt in the event of successes of failures. If exit codes are not set the exit code will be the exit code of the last run command.
How to get the exit code of a command ¶
To get the exit code of a command type echo $? at the command prompt. In the following example a file is printed to the terminal using the cat command.
cat file.txt hello world echo $? 0
The command was successful. The file exists and there are no errors in reading the file or writing it to the terminal. The exit code is therefore 0 .
In the following example the file does not exist.
cat doesnotexist.txt cat: doesnotexist.txt: No such file or directory echo $? 1
The exit code is 1 as the operation was not successful.
How to use exit codes in scripts ¶
To use exit codes in scripts an if statement can be used to see if an operation was successful.
#!/bin/bash cat file.txt if [ $? -eq 0 ] then echo "The script ran ok" exit 0 else echo "The script failed" >&2 exit 1 fi
If the command was successful the exit code will be 0 and ‘The script ran ok’ will be printed to the terminal.
How to set an exit code ¶
To set an exit code in a script use exit 0 where 0 is the number you want to return. In the following example a shell script exits with a 1 . This file is saved as exit.sh .
Executing this script shows that the exit code is correctly set.
What exit code should I use? ¶
The Linux Documentation Project has a list of reserved codes that also offers advice on what code to use for specific scenarios. These are the standard error codes in Linux or UNIX.
- 1 — Catchall for general errors
- 2 — Misuse of shell builtins (according to Bash documentation)
- 126 — Command invoked cannot execute
- 127 — “command not found”
- 128 — Invalid argument to exit
- 128+n — Fatal error signal “n”
- 130 — Script terminated by Control-C
- 255\* — Exit status out of range
How to suppress exit statuses ¶
Sometimes there may be a requirement to suppress an exit status. It may be that a command is being run within another script and that anything other than a 0 status is undesirable.
In the following example a file is printed to the terminal using cat. This file does not exist so will cause an exit status of 1 .
To suppress the error message any output to standard error is sent to /dev/null using 2>/dev/null .
If the cat command fails an OR operation can be used to provide a fallback — cat file.txt || exit 0 . In this case an exit code of 0 is returned even if there is an error.
Combining both the suppression of error output and the OR operation the following script returns a status code of 0 with no output even though the file does not exist.
#!/bin/bash cat 'doesnotexist.txt' 2>/dev/null || exit 0
Further reading ¶
Tags
Can you help make this article better? You can edit it here and send me a pull request.
See Also
- Linux and Unix cat command tutorial with examples
Aug 4, 2016
Tutorial on using cat, a UNIX and Linux command for concatenating files and printing to standard output. Examples of showing the contents of a file, appending one file to another, and combining multiple files into one. - Linux and Unix grep command tutorial with examples
Aug 3, 2016
Tutorial using grep, a UNIX and Linux command to print lines matching a pattern. Examples of finding text in a file, printing line numbers, counting the number of matches, searching recursively and ignoring case sensitivity. - Linux and Unix tee command tutorial with examples
Jul 28, 2016
Tutorial on using tee, a UNIX and Linux command for copying standard input to standard output and making a copy to one or more files. Examples of writing to a file, appending to a file and writing to a privileged file.
How to use Linux shell command exit codes
You can use the numeric codes returned by shell scripts or Ansible playbooks to identify problems and test the code.
When you execute a command in Linux, it generates a numeric return code. This happens whether you’re running the command directly from the shell, from a script, or even from an Ansible playbook. You can use those return codes to handle the result of that command properly.
What the return codes mean
When running commands at a shell prompt, the special variable $? contains a number that indicates the result of the last command executed.
A zero ( 0 ) means everything went fine. Anything else means there is a problem.
A value of 1 generically indicates that some error has happened.
$ who admin2 :1 2022-03-15 10:14 (:1) $ echo $? 0 $ who | grep thisstringdoesnotexist $ echo $? 1
In the example above, I executed the who command, which showed that I am admin2.
Immediately after that, I executed echo $? , and it returned zero because the previous command was executed successfully.
Then I executed the same who command (which I know is working fine) and piped that to grep with the non-existing argument. This time the $? variable contains a 1 .
Why? It’s because the last command executed was grep , which returns 1 when it cannot find the argument in its input.
$ls myfile.cfg ls: cannot access 'myfile.cfg': No such file or directory $echo $? 2
Here I tried to list a file that doesn’t exist. Then when I entered echo $? I got 2 , which is how the ls command indicates that the argument is not a file or directory name.
Customize the return code
You can also use the exit command from a shell script to customize the return code to the caller script.
The following script illustrates this:
#!/bin/bash if [ ! -f myfile.cfg ]; then echo The file does not exist and we display an error exit 64 fi echo The file exists and we will do something echo "(Not really doing anything, but this is where we could do it)" exit 0
$./myscrypt.sh The file does not exist and we display an error $echo $? 64 $touch myfile.cfg $./myscrypt.sh The file exists and we will do something (Not really doing anything, but this is where we could do it) $echo $? 0
Training & certification
In this script, I explicitly provide the exit code for the failed and for the successful cases. Some observations:
- If I do not explicitly use exit 0 , the return code from myscript.sh will be the return code from the last command executed inside it. This could be what I want, but here I wanted to state the return code pretty clearly inside the script.
- I used 64 as an arbitrary return code for the error condition. The Advanced Bash-Scripting Guide offers some guidelines about exit code values.
Test the return code with a shell script
If you need to test the return code of a command you invoked on your shell script, you just need to test the $? variable immediately after the command executes.
#!/bin/bash # A snipet from a shell script . # Next we will invoke a command or another shell script ./myscript.sh RETURN=$? if [ $RETURN -eq 0 ]; then echo "The script myscript.sh was executed successfuly" exit 0 else echo "The script myscript.sh was NOT executed successfuly and returned the code $RETURN" exit $RETURN fi
In this example, after invoking my command or script, I saved the exit code from $? on a variable for further utilization. (Again, $? returns the status of the last command, so you need to be careful if you run more commands—even a simple echo .).
Test the return code with an Ansible playbook
It is recommended to avoid running shell commands from an Ansible playbook if there is an Ansible module that performs the same action. This is especially because with a module you have better odds of being idempotent.
[ Ready to start automating? Check out this Ansible quick start series. ]
To illustrate how to handle return codes from a shell command, check this simple playbook:
--- - name: Executes a shell script hosts: localhost gather_facts: no tasks: - name: Execute the shell script shell: ./myscript.sh ignore_errors: true register: result - name: Shows the result of executing the script debug: msg: - "Return code. >" - ">"
This is the Ansible playbook executed when a script returns an error:
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' PLAY [Executes a shell script] ***************************************************************************************** TASK [Execute the shell script] **************************************************************************************** fatal: [localhost]: FAILED! => . ignoring TASK [Shows the result of executing the script] ************************************************************************ ok: [localhost] => < "msg": [ "Return code. 64", [ "The file does not exist and we display an error" ] ] >PLAY RECAP ************************************************************************************************************* localhost : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1