Ignoring specific errors in a shell script

BashShellError Handling

Bash Problem Overview


I have a small snippet of a shell script which has the potential to throw many errors. I have the script currently set to globally stop on all errors. However i would like for this small sub-section is slightly different.

Here is the snippet:

recover database using backup controlfile until cancel || true; 
auto

I'm expecting this to eventually throw a "file not found" error. However i would like to continue executing on this error. For any other error i would like the script to stop.

What would be the best method of achieving this?

Bash Version 3.00.16

Bash Solutions


Solution 1 - Bash

In order to cause bash to ignore errors for specific commands you can say:

some-arbitrary-command || true

This would make the script continue. For example, if you have the following script:

$ cat foo
set -e
echo 1
some-arbitrary-command || true
echo 2

Executing it would return:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found
2

In the absence of || true in the command line, it'd have produced:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found

Quote from the manual:

> The shell does not exit if the command that fails is part of the > command list immediately following a while or until keyword, part of > the test in an if statement, part of any command executed in a && or > || list except the command following the final && or ||, any command > in a pipeline but the last, or if the command’s return status is being > inverted with !. A trap on ERR, if set, is executed before the shell > exits.

EDIT: In order to change the behaviour such that in the execution should continue only if executing some-arbitrary-command returned file not found as part of the error, you can say:

[[ $(some-arbitrary-command 2>&1) =~ "file not found" ]]

As an example, execute the following (no file named MissingFile.txt exists):

$ cat foo 
#!/bin/bash
set -u
set -e
foo() {
  rm MissingFile.txt
}
echo 1
[[ $(foo 2>&1) =~ "No such file" ]]
echo 2
$(foo)
echo 3

This produces the following output:

$ bash foo 
1
2
rm: cannot remove `MissingFile.txt': No such file or directory

Note that echo 2 was executed but echo 3 wasn't.

Solution 2 - Bash

Use:

command || :

: is a bash built-in that always returns success. And, as discussed above, || short-circuits so the RHS is only executed if the LHS fails (returns non-zero).

The above suggestions to use 'true' will also work, but are inefficient as 'true' is an external program.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionStuntView Question on Stackoverflow
Solution 1 - BashdevnullView Answer on Stackoverflow
Solution 2 - BashChris CogdonView Answer on Stackoverflow