Linux command line exit status

Bash command line exit codes demystified

If you’ve ever wondered what an exit code is or why it’s a 0, 1, 2, or even 255, you’re in the right place.

Exit codes

Great Linux resources

When you execute a command or run a script, you receive an exit code. An exit code is a system response that reports success, an error, or another condition that provides a clue about what caused an unexpected result from your command or script. Yet, you might never know about the code, because an exit code doesn’t reveal itself unless someone asks it to do so. Programmers use exit codes to help debug their code.

Note: You’ll often see exit code referred to as exit status or even as exit status codes. The terms are used interchangeably except in documentation. Hopefully my use of the two terms will be clear to you.

I’m not a programmer. It’s hard for me to admit that, but it’s true. I’ve studied BASIC, FORTRAN, and a few other languages both formally and informally, and I have to say that I am definitely not a programmer. Oh sure, I can script and program a little in PHP, Perl, Bash, and even PowerShell (yes, I’m also a Windows administrator), but I could never make a living at programming because I’m too slow at writing code and trial-and-error isn’t an efficient debugging strategy. It’s sad, really, but I’m competent enough at copying and adapting found code that I can accomplish my required tasks. And yet, I also use exit codes to figure out where my problems are and why things are going wrong.

Exit codes are useful to an extent, but they can also be vague. For example, an exit code of 1 is a generic bucket for miscellaneous errors and isn’t helpful at all. In this article, I explain the handful of reserved error codes, how they can occur, and how to use them to figure out what your problem is. A reserved error code is one that’s used by Bash and you shouldn’t create your own error codes that conflict with them.

Enough backstory. It’s time to look at examples of what generates error codes/statuses.

Extracting the elusive exit code

To display the exit code for the last command you ran on the command line, use the following command:

The displayed response contains no pomp or circumstance. It’s simply a number. You might also receive a shell error message from Bash further describing the error, but the exit code and the shell error together should help you discover what went wrong.

Exit status 0

An exit status of 0 is the best possible scenario, generally speaking. It tells you that your latest command or script executed successfully. Success is relative because the exit code only informs you that the script or command executed fine, but the exit code doesn’t tell you whether the information from it has any value. Examples will better illustrate what I’m describing.

For one example, list files in your home directory. I have nothing in my home directory other than hidden files and directories, so nothing to see here, but the exit code doesn’t care about anything but the success of the command’s execution:

The exit code of 0 means that the ls command ran without issue. Although, again, the information from exit code provides no real value to me.

Читайте также:  Linux hostname допустимые символы

Now, execute the ls command on the /etc directory and then display the exit code:

$ ls /etc **Many files** $ echo $? 0

You can see that any successful execution results in an exit code of 0, including something that’s totally wrong, such as issuing the cat command on a binary executable file like the ls command:

$ cat /usr/bin/ls **A lot of screen gibberish and beeping** $ echo $? 0

Exit status 1

Using the above example but adding in the long listing and recursive options ( -lR ), you receive a new exit code of 1:

$ ls -lR /etc **A lengthy list of files** $ echo $? 1

Although the command’s output looks as though everything went well, if you scroll up you will see several «Permission denied» errors in the listing. These errors result in an exit status of 1, which is described as «impermissible operations.» Although you might expect that a «Permission denied» error leads to an exit status of 1, you’d be wrong, as you will see in the next section.

Dividing by zero, however, gives you an exit status of 1. You also receive an error from the shell to let you know that the operation you’re performing is «impermissible:»

$ let a=1 $ let b=0 $ let c=a/b -bash: let: c=a/b: division by 0 (error token is "b") $ echo $? 1 

Without a shell error, an exit status of 1 isn’t very helpful, as you can see from the first example. In the second example, you know why you received the error because Bash tells you with a shell error message. In general, when you receive an exit status of 1, look for the impermissible operations (Permission denied messages) mixed with your successes (such as listing all the files under /etc , as in the first example in this section).

Exit status 2

As stated above, a shell warning of «Permission denied» results in an exit status of 2 rather than 1. To prove this to yourself, try listing files in /root :

$ ls /root ls: cannot open directory '/root': Permission denied $ echo $? 2 

Exit status 2 appears when there’s a permissions problem or a missing keyword in a command or script. A missing keyword example is forgetting to add a done in a script’s do loop. The best method for script debugging with this exit status is to issue your command in an interactive shell to see the errors you receive. This method generally reveals where the problem is.

Permissions problems are a little less difficult to decipher and debug than other types of problems. The only thing «Permission denied» means is that your command or script is attempting to violate a permission restriction.

Exit status 126

Exit status 126 is an interesting permissions error code. The easiest way to demonstrate when this code appears is to create a script file and forget to give that file execute permission. Here’s the result:

$ ./blah.sh -bash: ./blah.sh: Permission denied $ echo $? 126 

This permission problem is not one of access, but one of setting, as in mode. To get rid of this error and receive an exit status of 0 instead, issue chmod +x blah.sh .

Note: You will receive an exit status of 0 even if the executable file has no contents. As stated earlier, «success» is open to interpretation.

I receiving an exit status of 126. This code actually tells me what’s wrong, unlike the more vague codes.

Exit status 127

Exit status 127 tells you that one of two things has happened: Either the command doesn’t exist, or the command isn’t in your path ( $PATH ). This code also appears if you attempt to execute a command that is in your current working directory. For example, the script above that you gave execute permission is in your current directory, but you attempt to run the script without specifying where it is:

$ blah.sh -bash: blah.sh: command not found $ echo $? 127 

If this result occurs in a script, try adding the explicit path to the problem executable or script. Spelling also counts when specifying an executable or a script.

Читайте также:  Как удалить альт линукс

Exit status 128

Exit status 128 is the response received when an out-of-range exit code is used in programming. From my experience, exit status 128 is not possible to produce. I have tried multiple actions for an example, and I can’t make it happen. However, I can produce an exit status 128-adjacent code. If your exit code exceeds 256, the exit status returned is your exit code subtracted by 256. This result sounds odd and can actually create an incorrect exit status. Check the examples to see for yourself.

Using an exit code of 261, create an exit status of 5:

$ bash $ exit 261 exit $ echo $? 5 

To produce an errant exit status of 0:

$ bash $ exit 256 exit $ echo $? 0 

If you use 257 as the exit code, your exit status is 1, and so on. If the exit code is a negative number, the resulting exit status is that number subtracted from 256. So, if your exit code is 20, then the exit status is 236.

Troubling, isn’t it? The solution, to me, is to avoid using exit codes that are reserved and out-of-range. The proper range is 0-255.

Exit status 130

If you’re running a program or script and press Ctrl-C to stop it, your exit status is 130. This status is easy to demonstrate. Issue ls -lR / and then immediately press Ctrl-C:

$ ls -lR / **Lots of files scrolling by** ^C $ echo $? 130 

There’s not much else to say about this one. It’s not a very useful exit status, but here it is for your reference.

Exit status 255

This final reserved exit status is easy to produce but difficult to interpret. The documentation that I’ve found states that you receive exit status 255 if you use an exit code that’s out of the range 0-255.

I’ve found that this status can also be produced in other ways. Here’s one example:

$ ip **Usage info for the ip command** $ echo $? 255 

Some independent authorities say that 255 is a general failure error code. I can neither confirm nor deny that statement. I only know that I can produce exit status 255 by running particular commands with no options.

Wrapping up

There you have it: An overview of the reserved exit status numbers, their meanings, and how to generate them. My personal advice is to always check permissions and paths for anything you run, especially in a script, instead of relying on exit status codes. My debug method is that when a command doesn’t work correctly in a script, I run the command individually in an interactive shell. This method works much better than trying fancy tactics with breaks and exits. I go this route because (most of the time) my errors are permissions related, so I’ve been trained to start there.

Have fun checking your statuses, and now it’s time for me to exit.

Читайте также:  Arch linux lvm install

[ Want to try out Red Hat Enterprise Linux? Download it now for free. ]

Источник

Bash Exit Status

Bash Exit Status

Regardless of whether a bash command ends successfully or not, it returns an exit status. Aside from letting you know that the command succeeded or failed, you can use the exit status code in bash scripts to determine what action to take with a conditional statement. The exit status of a bash command is always an integer (number). A successful command will have an exit status of zero (0), while a command that fails will have an exit status from 1 to 255. There is a special variable you can use to get the exit status of the previously executed command. You can easily print the exit status variable ($?) with the echo command. Take a look at this example or try it yourself: Here we run the date command and then print its exit status with the echo command.

Output: As you can see the date was printed on the first line and the successful exit status of zero on the second line.

Tue Oct 15 20:27:27 AST 2019 0

Testing with a bad command: Now we use the same example, but with a bad command (datefoo) that doesn’t exist.

Output: This now gives us a command not found error followed by the exit status code (127).

./test.sh: line 3: datefoo: command not found 127

Save the exit status in a variable: Saving the exit status for a command in a variable can be useful so that you can use the status later on in your bash script. In this example we run three commands and save the exit status for each in a variable. One of the commands is not a real command like in our previous example.

#!/bin/bash # Prints username echo $(whoami) var0=$? # Bad command datefoo var1=$? # Prints the time and date date var2=$? echo "These are the exit statuses for the commands above:" echo $var0 echo $var1 echo $var2
gametheory ./test.sh: line 8: datefoo: command not found Wed Oct 16 12:29:09 AST 2019 These are the exit statuses for the commands above: 0 127 0

Set the exit status in your bash script: Lets assume that we have a script called “test.sh” for this example. Here we have the cat command try to read a file that does not exist.

#!/bin/bash cat foo.txt if test $? -eq 0; then echo "The cat command succeeded because the file exists." exit 0 else echo "The cat command failed because the file does not exist." exit 1 fi

Output: Since our script was designed to fail for this example, we get the error message and exit status 1 that we declared ourselves.

cat: foo.txt: No such file or directory The cat command failed because the file does not exist. 1
  • 0 — Success
  • 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

Conclusion

This was a quick look at some bash exit status examples. Status exit codes can be quite useful. In large bash scripts it may be a good idea to set some exit status codes for easier troubleshooting of some parts of your code. They’re also great to setup conditional statements.

Источник

Оцените статью
Adblock
detector