忽略shell脚本中的特定错误

Stu*_*unt 48 error-handling bash shell

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

这是片段:

recover database using backup controlfile until cancel || true; 
auto
Run Code Online (Sandbox Code Playgroud)

我期待这最终会抛出"找不到文件"错误.但是,我想继续执行此错误.对于任何其他错误,我希望脚本停止.

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

Bash版本3.00.16

dev*_*ull 101

为了防止bash忽略特定命令的错误,你可以说:

some-arbitrary-command || true
Run Code Online (Sandbox Code Playgroud)

这将使脚本继续.例如,如果您有以下脚本:

$ cat foo
set -e
echo 1
some-arbitrary-command || true
echo 2
Run Code Online (Sandbox Code Playgroud)

执行它将返回:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found
2
Run Code Online (Sandbox Code Playgroud)

在没有|| true命令行的情况下,它产生了:

$ bash foo
1
z: line 3: some-arbitrary-command: command not found
Run Code Online (Sandbox Code Playgroud)

手册中引用:

如果失败的命令是紧跟在一个whileuntil关键字之后的命令列表的一部分,一个if语句中的测试的一部分,在一个&&||列表中执行的任何命令的一部分,除了在final之后的命令&&或者||任何命令之外,shell都不会退出管道但最后一个,或者如果命令的返回状态被反转!.ERR如果设置了陷阱,则在shell退出之前执行.

编辑:为了改变行为,只有当执行作为错误的一部分some-arbitrary-command返回时执行才应继续file not found,你可以说:

[[ $(some-arbitrary-command 2>&1) =~ "file not found" ]]
Run Code Online (Sandbox Code Playgroud)

例如,执行以下命令(没有名为MissingFile.txtexists的文件):

$ 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
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

$ bash foo 
1
2
rm: cannot remove `MissingFile.txt': No such file or directory
Run Code Online (Sandbox Code Playgroud)

请注意,echo 2已执行但未执行echo 3.


Chr*_*don 22

使用:

command || :
Run Code Online (Sandbox Code Playgroud)

:是一个内置的bash,总能返回成功.并且,如上所述,|| 短路所以只有在LHS失效时才会执行RHS(返回非零).

上述使用'true'的建议也可以使用,但效率低,因为'true'是一个外部程序.

  • 如果运行`/ bin/true`,则True只是一个外部程序,因为`true`本身就是一个内置bash的shell,就像echo和test一样,它也作为外部程序存在,但也是内置的在bash中如果你没有提供完整路径,将使用内置函数. (7认同)