Bash Shell Script Check Error Code
Contents |
exit codes, exit codes are important and this article describes how to use them in your scripts and understand them in general. bash shell script exit on error Written by Benjamin Cane on 2014-09-02 14:45:00| 4 min read Sponsored by Lately linux shell script exit on error I've been working on a lot of automation and monitoring projects, a big part of these projects are taking bash checking return code existing scripts and modifying them to be useful for automation and monitoring tools. One thing I have noticed is sometimes scripts use exit codes and sometimes they don't. It seems like shell script exit code exit codes are easy for poeple to forget, but they are an incredibly important part of any script. Especially if that script is used for the command line. What are exit codes? On Unix and Linux systems, programs can pass a value to their parent process while terminating. This value is referred to as an exit code or exit status. On POSIX systems the
Bash Exit Code Check
standard convention is for the program to pass 0 for successful executions and 1 or higher for failed executions. Why is this important? If you look at exit codes in the context of scripts written to be used for the command line the answer is very simple. Any script that is useful in some fashion will inevitably be either used in another script, or wrapped with a bash one liner. This becomes especially true if the script is used with automation tools like SaltStack or monitoring tools like Nagios, these programs will execute scripts and check the status code to determine whether that script was successful or not. On top of those reasons, exit codes exist within your scripts even if you don't define them. By not defining proper exit codes you could be falsely reporting successful executions which can cause issues depending on what the script does. What happens if I don't specify an exit code In Linux any script run from the command line has an exit code. With Bash scripts, if the exit code is not specified in the script itself the exit code us
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more
Bash Script Exit On Error
about Stack Overflow the company Business Learn more about hiring developers or posting ads exit bash shell with us Stack Overflow Questions Jobs Documentation Tags Users Badges Ask Question x Dismiss Join the Stack Overflow Community Stack Overflow bash return value from function is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute: Sign up Exit Shell Script Based on Process Exit Code up vote 238 down vote http://bencane.com/2014/09/02/understanding-exit-codes-and-how-to-use-them-in-bash-scripts/ favorite 76 I have a shell script that executes a number of commands. How do I make the shell script exit if any of the commands exit with a non-zero exit code? bash shell share|improve this question edited Jul 31 '11 at 19:12 Cerin 16.3k36138273 asked Sep 18 '08 at 6:03 Mark Roddy 10.7k95161 1 I answered assuming you're using bash, but if it's a very different shell http://stackoverflow.com/questions/90418/exit-shell-script-based-on-process-exit-code can you specify in your post? –Martin W Sep 18 '08 at 6:11 add a comment| 9 Answers 9 active oldest votes up vote 312 down vote accepted After each command, the exit code can be found in the $? variable so you would have something like: ls -al file.ext rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi You need to be careful of piped commands since the $? only gives you the return code of the last element in the pipe so, in the code: ls -al file.ext | sed 's/^/xx: /" will not return an error code if the file doesn't exist (since the sed part of the pipeline actually works, returning 0). The bash shell actually provides an array which can assist in that case, that being PIPESTATUS. This array has one element for each of the pipeline components, that you can access individually like ${PIPESTATUS[0]}: pax> false | true ; echo ${PIPESTATUS[0]} 1 Note that this is getting you the result of the false command, not the entire pipeline. You can also get the entire list to process as you see fit: pax> false | true | false; echo ${PIPESTATUS[*]} 1 0 1 If you wanted to get the la
here for a quick overview of the site Help Center Detailed answers to any questions you might have Meta Discuss the workings and policies of this site About Us Learn more about Stack Overflow the company Business Learn more about http://unix.stackexchange.com/questions/209419/how-to-keep-last-exit-status-after-test hiring developers or posting ads with us Unix & Linux Questions Tags Users Badges Unanswered Ask https://sanctum.geek.nz/arabesque/testing-exit-values-bash/ Question _ Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute: Sign up Here's how it works: Anybody can ask a question Anybody can answer The best answers are voted up and rise to the top How to keep last exit status after test up shell script vote 7 down vote favorite Is it possible to keep the last command exit status ($?) unaltered after a test? E.g., I would like to do: command -p sudo ... [ $? -ne 1 ] && exit $? The last exit $? should return the sudo exit status, but instead it always returns 0 (the exit code of the test). Is it possible to do that without a temporary variable? Another example to clarify further: spd-say "$@" [ $? -ne shell script exit 127 ] && exit $? In this case i want to exit only if the first command is found (exit code != 127). And i want to exit with the actual spd-say exit code (it may not be 0). EDIT: I forgot to mention that i prefer a POSIX-complaint solution for better portability. I use this construct in scripts where i want to provide alternatives for the same command. For instance, see my crc32 script. The problem with temporary variables is that they could shadow other variables, and to avoid that you must use long names, which is not good for code readability. shell-script variable return-status share|improve this question edited Jul 15 '15 at 4:28 Evgeny Vereshchagin 1,8522721 asked Jun 13 '15 at 13:35 eadmaster 351414 No, but you can just do if ! command -p sudo; then exit; fi which would have the same results for your example. –jordanm Jun 13 '15 at 13:44 ok, what if i want to test for the 127 code instead? (eg. [ $? -ne 127 ] && exit $?) –eadmaster Jun 13 '15 at 13:47 1 @jordanm: Really? If the OP has presented the code/logic he meant to, and if I'm reading it correctly, he wants the script to exit if the sudo command succeeds (i.e., if sudo exits with status 0). But, in your code, the script keeps running (doesn't exit) if sudo succeeds –G-Man
Ryder In Bash scripting (and shell scripting in general), we often want to check the exit value of a command to decide an action to take after it completes, likely for the purpose of error handling. For example, to determine whether a particular regular expression regex was present somewhere in a file options, we might apply grep(1) with its POSIX -q option to suppress output and just use the exit value: grep -q regex options An approach sometimes taken is then to test the exit value with the $? parameter, using if to check if it's non-zero, which is not very elegant and a bit hard to read: # Bad practice grep -q regex options if (($? > 0)); then printf '%s\n' 'myscript: Pattern not found!' >&2 exit 1 fi Because the if construct by design tests the exit value of commands, it's better to test the command directly, making the expansion of $? unnecessary: # Better if grep -q regex options; then # Do nothing : else printf '%s\n' 'myscript: Pattern not found!\n' >&2 exit 1 fi We can precede the command to be tested with ! to negate the test as well, to prevent us having to use else as well: # Best if ! grep -q regex options; then printf '%s\n' 'myscript: Pattern not found!' >&2 exit 1 fi An alternative syntax is to use && and || to perform if and else tests with grouped commands between braces, but these tend to be harder to read: # Alternative grep -q regex options || { printf '%s\n' 'myscript: Pattern not found!' >&2 exit 1 } With this syntax, the two commands in the block are only executed if the grep(1) call exits with a non-zero status. We can apply && instead to execute commands if it does exit with zero. That syntax can be convenient for quickly short-circuiting failures in scripts, for example due to nonexistent commands, particularly if the command being tested already outputs its own error message. This therefore cuts the script off if the given command fails, likely due to ffmpeg(1) being unavailable on the system: hash ffmpeg || exit 1 Note that the braces for a grouped command are not needed here, as there's only one command to be run in case of failure, the exit call. Calls to cd are another good use case here, as running a script in the wrong directory if a call to cd fails could have really nasty effects: cd wherever || exit 1 In general, you'll probably only want to test $? when you have specific non-zero erro