忽略 shell 脚本中的特定错误

我有一个 shell 脚本的小片段,它有可能抛出许多错误。我的脚本当前设置为全局停止所有错误。不过我想对这个小分节略有不同。

下面是一个片段:

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

我希望这最终会抛出一个“ file not found”错误。但是我想继续执行这个错误。对于任何其他错误,我希望脚本停止。

实现这一目标的最佳方法是什么?

Bash 版本3.00.16

128649 次浏览

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.

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.