How to Use Exit Codes in Shell Scripts

Every command returns an exit status, also commonly referred to as return status or exit code. A successful command exits with an exit status of 0. Unsuccessful commands exit with a nonzero exit status. Upon completion, a command’s exit status is passed to the parent process and stored in the ? variable. Therefore, the exit status of an executed command can be retrieved by displaying the value of $?. The following examples demonstrate the execution and exit status retrieval of several common commands.

$ ls /etc/hosts
/etc/hosts

$ echo $?
0
$ ls /etc/nofile
ls: cannot access /etc/nofile: No such file or directory

$ echo $?
2
$ grep localhost /etc/hosts
# localhost is used to configure the loopback interface
127.0.0.1	localhost
::1             localhost

$ echo $?
0
$ grep random /etc/hosts

$ echo $?
1

Using exit codes within a script

Once executed, a script will exit when it has processed all of its contents. However, there may be times when it is desirable to exit a script midway through, such as when an error condition is encountered. This can be accomplished with the use of the exit command within a script. When a script encounters the exit command, it will exit immediately and skip the processing of the remainder of the script.

The exit command can be executed with an optional integer argument between 0 and 255, which represents an exit code. An exit code value of 0 represents no error. All other nonzero values indicate an error exit code. Script authors can use different nonzero values to differentiate between different types of errors encountered. This exit code is passed back to the parent process, which stores it in the ? variable and can be accessed with $? as demonstrated in the following examples.

$ cat hello
#!/bin/bash
echo "Hello, world"
exit 0
$ ./hello Hello,
world

$ echo $?
0
$ cat hello
#!/bin/bash
echo "Hello, world"
exit 1
$ ./hello Hello,
world

$ echo $?
1

If the exit command is called without an argument, then the script will exit and pass on to the parent process the exit status of the last command executed.