4

I've been told in php it's preferred to avoid the use of the exit command as much as possible.

Is the same true for bash?

For example is the following

#!/bin/bash
if [ -z $1 ]; then
        echo You need to enter the directory you want to backup
else
        sourceFile=$1
        targetFile=/home/me/Desktop/myBackups/files_$(date +%Y_%m_%d_%s)
        tar cvf $targetFile $sourceFile
fi

Preferred to this?

#!/bin/bash
if [ -z $1 ]; then
        echo You need to enter the directory you want to backup
        exit
fi
        sourceFile=$1
        targetFile=/home/me/Desktop/myBackups/files_$(date +%Y_%m_%d_%s)
        tar cvf $targetFile $sourceFile
1
  • actually, using exit would be a recommended practice. in the abs-guide, for example, most scripts ends with exit 0.
    – elias
    Dec 5, 2011 at 12:38

3 Answers 3

6

Quoting 'Code Complete'

Use [exit] when it enhances readability In certain routines, once you know the answer, you want to [exit] to the calling routine immediately. If the routine is defined in such a way that it doesn’t require any further cleanup once it detects an error, not [exiting] immediately means that you have to write more code.

So normally one exit is preferred (people looking at your code don't have to find the correct exit statement), however with error checking (especially at the start of a program/routine having multiple exit statements is clearer.

Your example is borderline, however I would say that the second is preferred so that maintenance to your program/script can leave it tidy.

Your program currently is (in psudocode)

if error condition 1
    // Show error message 1
else
    // Do stuff
fi

or

if error condition 1
    // Show error message 1
    // exit
fi

// Do stuff

Once your program has grown, you realise some more ways that the program can fail. Your program now becomes

if error condition 1
    // Show error message 1
else 
    if error condition 2
         // Show error message 2
    else
         if error condition 3
             // Show error message 3
         else
             // Do stuff
         fi
    fi
fi

or maybe

if error condition 1
    // Show error message 1
else if error condition 2
    // Show error message 2
else if error condition 3
    // Show error message 3
else
    // Do stuff
fi

versus

if error condition 1
    // Show error message 1
    // exit
else if error condition 2
    // Show error message 2
    // exit
else if error condition 3
    // Show error message 3
    // exit
fi

// Do stuff

In my mind, the last one is the clearest in being able to spot which is the error cases and which is the main flow of the program. Now add returning different values (eg. 0 on success, 1 on error 1, 2 on error 2, etc.) and the difference will become more pronounced.

2

I suppose it depends on the script to some extent on your code and what you are trying to accomplish, traps, error handling, etc.

In general you are going to either want to specify an exit status

exit 1

or set -e

#!/bin/bash -e

You can add error management in a variety of ways

command 1 || echo "command 1 failed"

to writing functions to traps.

There are a few nice (introductory) discussions with references :

1

My preference is this:

#!/bin/bash
if [[ -z "$1" ]]; then
        # Notice that I added quotes and redirection
        echo "You need to enter the directory you want to backup" 1>&2
        exit
fi
# Notice that I fixed the indentation
sourceFile="$1"
targetFile="/home/me/Desktop/myBackups/files_$(date +%Y_%m_%d_%s)"
tar cvf "$targetFile" "$sourceFile"

I think exiting at the point where it's clear that the program can't continue or where it's clearly finished makes for the cleanest code.

On an unrelated note, beware of unquoted strings in Bash. They'll bite you sooner or later. It's a good habit to always surround strings with double quotes (even when it's technically unnecessary) unless you specifically want the unquoted behavior. Also, as long as you're using bash, [[ is much better than [.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .