- Exit command
- Contents
- Purpose
- Syntax
- Examples
- Exit status at the CLI
- Execute commands based upon the exit status
- Shell script example
- Как использовать коды завершения в Bash-скриптах
- Что такое коды завершения
- Что происходит, когда коды завершения не определены
- Как использовать коды завершения в Bash-скриптах
- Проверяем коды завершения
- Создаём собственный код завершения
- Как использовать коды завершения в командной строке
- Дополнительные коды завершения
- Linux bash exit status and how to set exit status in bash
- More on Linux bash shell exit status codes
- How do I display the exit status of shell command?
- How to store the exit status of the command in a shell variable
- Linux exit status and the conditional/list constructs
- How to use the && and || operators with exit codes
- List of common exit codes for GNU/Linux
- Conclusion
Exit command
Sometimes we need to stop the execution of our script when a condition is satisfied. For example, if tar command not installed, stop the execution of our shell script. We can also take action based on the exit code of the command. Say if ping command is successful, continue with script or exit with an error. Let us see how to use the exit command and the exit statuses in our scripts.
Contents
Purpose
Exit the bash shell or shell script with a status of N.
Syntax
The syntax is as follows:
- The exit statement is used to exit from the shell script with a status of N.
- Use the exit statement to indicate successful or unsuccessful shell script termination.
- The value of N can be used by other commands or shell scripts to take their own action.
- If N is omitted, the exit status is that of the last command executed.
- Use the exit statement to terminate shell script upon an error.
- If N is set to 0 means normal shell exit.
Examples
Create a shell script called exitcmd.sh:
Save and close the file. Run it as follows:
To see exit status of the script, enter (see the exit status of a command for more information about special shell variable $?) :
Exit status at the CLI
Exit status is not limited to shell script. Every time command terminated shell gets an exit code indicating success or failure of the command. Hence we can use the particular bash variable $? to get the exit status of the command. For instance:
In this example, we will see the exit status of the last command (command3) only:
Execute commands based upon the exit status
Run command2 if command1 is successful using Logical AND ( && ) operator:
For example, if wget command found in execute the echo command
Similarly, bar command is executed if, and only if, foo command returns a non-zero exit status using Logical OR operator:
Therefore we can combine bash Exit command and exit codes to build quick logic as follows:
We can group commands as a unit as follows:
Shell script example
- Any non zero value indicates unsuccessful shell script termination.
- Create a shell script called datatapebackup.sh:
Save and close the file. Run it as follows:
All of our shell commands return an exit code when terminated successfully or abnormally. We can use the exit command in our shell script to provide the exit code. We also learned how to harness the exit status’s power to build logic in a shell script or at the command line.
Источник
Как использовать коды завершения в Bash-скриптах
Инструменты автоматизации и мониторинга удобны тем, что разработчик может взять готовые скрипты, при необходимости адаптировать и использовать в своём проекте. Можно заметить, что в некоторых скриптах используются коды завершения (exit codes), а в других нет. О коде завершения легко забыть, но это очень полезный инструмент. Особенно важно использовать его в скриптах командной строки.
Что такое коды завершения
В Linux и других Unix-подобных операционных системах программы во время завершения могут передавать значение родительскому процессу. Это значение называется кодом завершения или состоянием завершения. В POSIX по соглашению действует стандарт: программа передаёт 0 при успешном исполнении и 1 или большее число при неудачном исполнении.
Почему это важно? Если смотреть на коды завершения в контексте скриптов для командной строки, ответ очевиден. Любой полезный Bash-скрипт неизбежно будет использоваться в других скриптах или его обернут в однострочник Bash. Это особенно актуально при использовании инструментов автоматизации типа SaltStack или инструментов мониторинга типа Nagios. Эти программы исполняют скрипт и проверяют статус завершения, чтобы определить, было ли исполнение успешным.
Кроме того, даже если вы не определяете коды завершения, они всё равно есть в ваших скриптах. Но без корректного определения кодов выхода можно столкнуться с проблемами: ложными сообщениями об успешном исполнении, которые могут повлиять на работу скрипта.
Что происходит, когда коды завершения не определены
В Linux любой код, запущенный в командной строке, имеет код завершения. Если код завершения не определён, Bash-скрипты используют код выхода последней запущенной команды. Чтобы лучше понять суть, обратите внимание на пример.
Этот скрипт запускает команды touch и echo . Если запустить этот скрипт без прав суперпользователя, команда touch не выполнится. В этот момент мы хотели бы получить информацию об ошибке с помощью соответствующего кода завершения. Чтобы проверить код выхода, достаточно ввести в командную строку специальную переменную $? . Она печатает код возврата последней запущенной команды.
Как видно, после запуска команды ./tmp.sh получаем код завершения 0 . Этот код говорит об успешном выполнении команды, хотя на самом деле команда не выполнилась. Скрипт из примера выше исполняет две команды: touch и echo . Поскольку код завершения не определён, получаем код выхода последней запущенной команды. Это команда echo , которая успешно выполнилась.
Если убрать из скрипта команду echo , можно получить код завершения команды touch .
Поскольку touch в данном случае — последняя запущенная команда, и она не выполнилась, получаем код возврата 1 .
Как использовать коды завершения в Bash-скриптах
Удаление из скрипта команды echo позволило нам получить код завершения. Что делать, если нужно сделать разные действия в случае успешного и неуспешного выполнения команды touch ? Речь идёт о печати stdout в случае успеха и stderr в случае неуспеха.
Проверяем коды завершения
Выше мы пользовались специальной переменной $? , чтобы получить код завершения скрипта. Также с помощью этой переменной можно проверить, выполнилась ли команда touch успешно.
После рефакторинга скрипта получаем такое поведение:
- Если команда touch выполняется с кодом 0 , скрипт с помощью echo сообщает об успешно созданном файле.
- Если команда touch выполняется с другим кодом, скрипт сообщает, что не смог создать файл.
Любой код завершения кроме 0 значит неудачную попытку создать файл. Скрипт с помощью echo отправляет сообщение о неудаче в stderr .
Создаём собственный код завершения
Наш скрипт уже сообщает об ошибке, если команда touch выполняется с ошибкой. Но в случае успешного выполнения команды мы всё также получаем код 0 .
Поскольку скрипт завершился с ошибкой, было бы не очень хорошей идеей передавать код успешного завершения в другую программу, которая использует этот скрипт. Чтобы добавить собственный код завершения, можно воспользоваться командой exit .
Теперь в случае успешного выполнения команды 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. Мнение администрации Хекслета может не совпадать с мнением автора оригинальной публикации.
Источник
Linux bash exit status and how to set exit status in bash
C an you explain bash exit status code? How do I set bash exit status in my Linux shell scripts?
Each Linux or Unix command returns a status when it terminates normally or abnormally. You can use value of exit status in the shell script to display an error message or run commands. For example, if tar command is unsuccessful, it returns a code which tells the shell script to send an e-mail to sysadmins.
Tutorial details | |
---|---|
Difficulty level | Easy |
Root privileges | No |
Requirements | Bash running on Linux, macOS or Unix |
Est. reading time | 3 minutes |
More on Linux bash shell exit status codes
- Every Linux or Unix command executed by the shell script or user, has an exit status.
- The exit status is an integer number.
- For the bash shell’s purposes, a command which exits with a zero (0) exit status has succeeded.
- A non-zero (1-255) exit status indicates failure.
- If a command is not found, the child process created to execute it returns a status of 127. If a command is found but is not executable, the return status is 126.
- All of the Bash builtins return exit status of zero if they succeed and a non-zero status on failure.
How do I display the exit status of shell command?
You can use special shell variable called $? to get the exit status of the previously executed command. To print $? variable use the echo command/printf command. The syntax is:
command
echo $?
OR
/path/to/script.sh
command
date
echo $?
## OR use the printf command ##
printf «%d\n» $?
## run non-existence command ##
foobar13535
## display status code ##
echo $?
How to store the exit status of the command in a shell variable
Assign $? to a shell variable. The syntax is:
Linux exit status and the conditional/list constructs
A simple shell script to locate host name (findhost.sh)
How to use the && and || operators with exit codes
If a dir named “/tmp/foo” not found create it:
[ ! -d «/tmp/foo» ] && mkdir -p «/tmp/foo»
For example, show usage syntax when filename not passed as the command line arg:
- No ads and tracking
- In-depth guides for developers and sysadmins at Opensourceflare✨
- Join my Patreon to support independent content creators and start reading latest guides:
- How to set up Redis sentinel cluster on Ubuntu or Debian Linux
- How To Set Up SSH Keys With YubiKey as two-factor authentication (U2F/FIDO2)
- How to set up Mariadb Galera cluster on Ubuntu or Debian Linux
- A podman tutorial for beginners – part I (run Linux containers without Docker and in daemonless mode)
- How to protect Linux against rogue USB devices using USBGuard
Join Patreon ➔
Here is another shell script that shows usage:
List of common exit codes for GNU/Linux
Exit Code | Description |
---|---|
0 | Success |
1 | Operation not permitted |
2 | No such file or directory |
3 | No such process |
4 | Interrupted system call |
5 | Input/output error |
6 | No such device or address |
7 | Argument list too long |
8 | Exec format error |
9 | Bad file descriptor |
10 | No child processes |
11 | Resource temporarily unavailable |
12 | Cannot allocate memory |
13 | Permission denied |
14 | Bad address |
15 | Block device required |
16 | Device or resource busy |
17 | File exists |
18 | Invalid cross-device link |
19 | No such device |
20 | Not a directory |
21 | Is a directory |
22 | Invalid argument |
23 | Too many open files in system |
24 | Too many open files |
25 | Inappropriate ioctl for device |
26 | Text file busy |
27 | File too large |
28 | No space left on device |
29 | Illegal seek |
30 | Read-only file system |
31 | Too many links |
32 | Broken pipe |
33 | Numerical argument out of domain |
34 | Numerical result out of range |
35 | Resource deadlock avoided |
36 | File name too long |
37 | No locks available |
38 | Function not implemented |
39 | Directory not empty |
40 | Too many levels of symbolic links |
42 | No message of desired type |
43 | Identifier removed |
44 | Channel number out of range |
45 | Level 2 not synchronized |
46 | Level 3 halted |
47 | Level 3 reset |
48 | Link number out of range |
49 | Protocol driver not attached |
50 | No CSI structure available |
51 | Level 2 halted |
52 | Invalid exchange |
53 | Invalid request descriptor |
54 | Exchange full |
55 | No anode |
56 | Invalid request code |
57 | Invalid slot |
59 | Bad font file format |
60 | Device not a stream |
61 | No data available |
62 | Timer expired |
63 | Out of streams resources |
64 | Machine is not on the network |
65 | Package not installed |
66 | Object is remote |
67 | Link has been severed |
68 | Advertise error |
69 | Srmount error |
70 | Communication error on send |
71 | Protocol error |
72 | Multihop attempted |
73 | RFS specific error |
74 | Bad message |
75 | Value too large for defined data type |
76 | Name not unique on network |
77 | File descriptor in bad state |
78 | Remote address changed |
79 | Can not access a needed shared library |
80 | Accessing a corrupted shared library |
81 | .lib section in a.out corrupted |
82 | Attempting to link in too many shared libraries |
83 | Cannot exec a shared library directly |
84 | Invalid or incomplete multibyte or wide character |
85 | Interrupted system call should be restarted |
86 | Streams pipe error |
87 | Too many users |
88 | Socket operation on non-socket |
89 | Destination address required |
90 | Message too long |
91 | Protocol wrong type for socket |
92 | Protocol not available |
93 | Protocol not supported |
94 | Socket type not supported |
95 | Operation not supported |
96 | Protocol family not supported |
97 | Address family not supported by protocol |
98 | Address already in use |
99 | Cannot assign requested address |
100 | Network is down |
101 | Network is unreachable |
102 | Network dropped connection on reset |
103 | Software caused connection abort |
104 | Connection reset by peer |
105 | No buffer space available |
106 | Transport endpoint is already connected |
107 | Transport endpoint is not connected |
108 | Cannot send after transport endpoint shutdown |
109 | Too many references |
110 | Connection timed out |
111 | Connection refused |
112 | Host is down |
113 | No route to host |
114 | Operation already in progress |
115 | Operation now in progress |
116 | Stale file handle |
117 | Structure needs cleaning |
118 | Not a XENIX named type file |
119 | No XENIX semaphores available |
120 | Is a named type file |
121 | Remote I/O error |
122 | Disk quota exceeded |
123 | No medium found |
125 | Operation canceled |
126 | Required key not available |
127 | Key has expired |
128 | Key has been revoked |
129 | Key was rejected by service |
130 | Owner died |
131 | State not recoverable |
132 | Operation not possible due to RF-kill |
133 | Memory page has hardware error |
The perror command explain error codes which is part of MySQL/MariaDB package:
perror 0
perror 1
Conclusion
This page explained bash exit status and related commands. For more info see bash shell man page here.
🐧 Get the latest tutorials on Linux, Open Source & DevOps via
Источник