7

Pretty new to shell scripting. I am trying to do the following:

#!/bin/bash

unzip myfile.zip

#do stuff if unzip successful

I know that I can just chain the commands together in with && but there is quite a chunk, it would not be terribly maintainable.

2
  • 2
    possible duplicate of Aborting a shell script if any command returns a non-zero value? Commented Jun 4, 2013 at 13:45
  • 1
    No way, this isn't a dupe, and I'm surprised anyone thinks it is. That question is about aborting an entire script based on any unsuccessful statement, this one is about exiting if a specific statement is unsuccessful. Commented Jun 6, 2013 at 13:52

4 Answers 4

12

You can use the exit status of the command explicitly in the test:

if ! unzip myfile.zip &> /dev/null; then
    # handle error
fi
Sign up to request clarification or add additional context in comments.

1 Comment

@MildFuzz /dev/null is the bit-bucket, you can redirect anything you like to it and it will get thrown away. 2>&1 tells it to direct stderr to the stdout.
11

You can use $?. It returns:
- 0 if the command was successfully executed.
- !0 if the command was unsuccessful.

So you can do

#!/bin/bash

unzip myfile.zip

if [ "$?" -eq 0 ]; then
    #do stuff on unzip successful
fi

Test

$ cat a
hello
$ echo $?
0
$ cat b
cat: b: No such file or directory
$ echo $?
1

6 Comments

This is mostly correct. Most processes return 0 on success and non-zero on failure. It won't necessarily be 1.
This works, but it's not entirely correct. $? contains the exit status of the most recently executed command. That depends on the command and, in the case of the unzip command there are 17 possible return values. The information about exit status is usually found in the man page for the command.
[ $? ] && echo "error!" will echo error even if $? is 0. It tests whether the string is empty, not whether the string is nonzero.
@CharlesDuffy mm, true. Quite a lot of time since I wrote this, but I guess [ "$?" -eq 0 ] is the way to go?
if unzip myfile.zip; then would be even better, but yes, if you're going to do the comparison after-the-fact, your above comment is an improvement on what's in the answer now.
|
5

The variable $? contains the exit status of the previous command. A successful exit status for (most) commands is (usually) 0, so just check for that...

#!/bin/bash
unzip myfile.zip

if [ $? == 0 ]
then
    # Do something
fi

3 Comments

By definition, a command is successful if and only if it has an exit status of zero.
@WilliamPursell I'm sure someone has a definition which says a command is successful if and only if it has an exit status of 0, but that's wrong. It's impossible since "success" is subjective and isn't always boolean. An exit status of 0 indicates only that a condition has been met. For example grep returns 0 if it has found a pattern and 1 if it hasn't. The exit status of 1 indicates that it has executed successfully, but hasn't found the pattern. Add the -q option and it returns 0 even if there's an error. In contrast, find returns 0 even if it hasn't found its pattern.
Why would you do this rather than if unzip myfile.zip; then : "Do something"; fi? Decoupling through $? just adds potential for bugs -- add an echo between your unzip and your if, and suddenly $? reflects the exit status of the logging statement, not the unzip command.
4

If you want the shell to check the result of the executed commands and stop interpretation when something returns non-zero value you can add set -e which means Exit immediately if a command exits with a non-zero status. I'm using this often in scripts.

#!/bin/sh

set -e

# here goes the rest

1 Comment

You say -e, but you use -x in your example. Also, you could just put it in your shebang: #!/bin/sh -e.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.