How to perform a command without causing the script to abort, either by not executing the command or forcing a success result.

The assumption is this set as start of the script such that any errors would cause the script to abort.

set -e

Default

Assume that CMD references a failing command such as running copy, move or remove on a file or folder that is not valid to operate on. e.g. rm foo.txt when foo.txt does not exist.

CMD

Run echo $? after and you’ll see 1 or another error status code.

You’ll also have any error messages logged on stderr.

Continue without aborting

If a step is optional or will only be needed sometimes (like deleting a temporary file which won’t exist on the very first run).

CMD || true

If you run echo $? you’ll see 0 for success, as it uses the exit code for the entire line above it (which will come from the last executed piece).

Run quietly

Silence stderr, but keep stdout.

CMD &> /dev/null

Continue without aborting and fail silently

Combine the sections above:

CMD &> /dev/null || true

Run conditionally

You could add a targeted if statement to check that a file or folder is already there or not, rather than using a catchall as in the previous sections.

You could check if file exists and is readable and is executable. Or just pick one of those tests.

# Optional command
if [ -f foo.txt ]; then
  rm foo.txt
fi

# More commands

Here is a directory check in one line.

# Optional command.
[ -d foo ] && rm -rf foo

# More commands

Maybe you want to check it is empty.

[ -z foo.txt ]

There could be multiple reasons for the command to fail and you’d have to catch them all.

Here is a DRY approach (replace source with echo to just print).

test -f ~/.git-completion.sh && source $_

That uses the last argument of previous command on the same line and uses it in place of $_.

Now this only works with the test CONDITION syntax. Using [[ CONDITION ]] ends up using ]] instead of the path.

Compare with this (which works only works in interactive mode I think):

test -f ~/.git-completion.sh
source !$

Also in ZSH, you have to press enter a second time at the end to confirm the substitution.

Set error flag

You could also reverse the error flag so that errors are not fatal. This can be especially useful for ignoring errors on a series of lines.

set -e

# Do stuff.

set +e
# Do stuff that can fail.

set -e

# Do more stuff.