How to use exit codes and test inputs in Shell Scripts

Using exit codes within a script

After a script has processed all of its contents, it exits to the process that called it. However, there may be times when it is desirable to exit a script before it finishes, 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 exits immediately and does not process 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 is a code that is returned after a process has completed. An exit code value of 0 represents no error. All other nonzero values indicate an error exit code. You 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.

[user@host bin]$ cat hello
echo "Hello, world"
exit 0
[user@host bin]$ ./hello
Hello, world
[user@host bin]$ echo $?

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

Testing script inputs

To ensure that scripts are not easily disrupted by unexpected conditions, it is good practice to not make assumptions regarding input, such as command-line arguments, user input, command substitutions, variable expansions, and file-name expansions. Integrity checking can be performed by using Bash’s test command. Like all commands, the test command produces an exit code upon completion, which is stored as the value $?. To see the conclusion of a test, display the value of $? immediately following the execution of the test command. Again, an exit status value of 0 indicates the test succeeded, and nonzero values indicate the test failed.

Tests are performed using a variety of operators. Operators can be used to determine if a number is greater than, greater than or equal to, less than, less than or equal to, or equal to another number. They can be used to test if a string of text is the same or not the same as another string of text. Operators can also be used to evaluate if a variable has a value or not.

The following examples demonstrate the use of the test command using Bash’s numeric comparison operators.

[user@host ~]$ test 1 -gt 0 ; echo $?
[user@host ~]$ test 0 -gt 1 ; echo $?

Tests can be performed using the Bash test command syntax, [ TESTEXPRESSION ]. They can also be performed using Bash’s newer extended test command syntax, [[ TESTEXPRESSION ]], which has been available since Bash version 2.02 and provides features such as glob pattern matching and regex pattern matching.

The following examples demonstrate the use of Bash’s test command syntax and Bash’s numeric comparison operators.

[user@host ~]$ [ 1 -eq 1 ]; echo $?

[user@host ~]$ [ 1 -ne 1 ]; echo $?

[user@host ~]$ [ 8 -gt 2 ]; echo $?

[user@host ~]$ [ 2 -ge 2 ]; echo $?

[user@host ~]$ [ 2 -lt 2 ]; echo $?

[user@host ~]$ [ 1 -lt 2 ]; echo $?

The following examples demonstrate the use of Bash’s string comparison operators.

[user@host ~]$ [ abc = abc ]; echo $?

[user@host ~]$ [ abc == def ]; echo $?

[user@host ~]$ [ abc != def ]; echo $?

The following examples demonstrate the use of Bash’s string unary operators.

[user@host ~]$ STRING=''; [ -z "$STRING" ]; echo $?

[user@host ~]$ STRING='abc'; [ -n "$STRING" ]; echo $?