Linux shell试试看终于

Jet*_*tse 62 syntax shell finally try-catch

有没有像linux try catch一样的linux bash命令?或者linux shell总是继续?

try {
   `executeCommandWhichCanFail`
   mv output
} catch {
    mv log
} finally {
    rm tmp
}
Run Code Online (Sandbox Code Playgroud)

Fai*_*aiz 93

好吧,有点:

{ # your 'try' block
    executeCommandWhichCanFail &&
    mv output
} || { # your 'catch' block
    mv log
}

 rm tmp # finally: this will always happen
Run Code Online (Sandbox Code Playgroud)

  • 注意你必须在`executeCommandWhichCanFail`之后使用`&&`,否则它会盲目地继续.即使你先使用`set -e`(我不明白). (4认同)
  • 简洁明了.但是我更喜欢使用`trap`,因为`||`不能确保即使在异常条件(信号)下也能执行其他部分,这几乎是人们对`finally`的期望. (2认同)

小智 90

根据您的示例,无论脚本如何退出,您似乎都在尝试执行类似于始终删除临时文件的操作.在Bash中这样做尝试trap内置命令来捕获EXIT信号.

#!/bin/bash

trap 'rm tmp' EXIT

if executeCommandWhichCanFail; then
    mv output
else
    mv log
    exit 1 #Exit with failure
fi

exit 0 #Exit with success
Run Code Online (Sandbox Code Playgroud)

脚本退出时始终执行该rm tmp语句trap,因此将始终尝试删除文件"tmp".

安装的陷阱也可以重置; 仅使用信号名称调用陷阱将重置信号处理程序.

trap EXIT
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅bash手册页: man bash

  • 从快速测试来看,似乎``EXIT`处理程序**也被称为`SIGINT`和`SIGTERM` (4认同)
  • 使用“陷阱”的一个好处是,除了 EXIT 之外,您还可以捕获其他信号。特别是,您可以捕获 SIGINT (Control-C)。为此,只需将其添加到陷阱语句的末尾即可。例如`trap 'rm tmp' EXIT SIGINT`。 (3认同)
  • 这肯定是最干净的方法。 (3认同)
  • 好答案; 值得指出的是,陷阱的执行不会影响脚本的退出状态-这是优于`if / else`或`||`方法的优势,更像是C ++或Java`try` /`catch `。 (2认同)
  • 扩展上述评论:在我的测试中,Control-C 首先触发 SIGINT,然后是 EXIT。因此,出于此处讨论的目的,捕获 SIGINT 是多余的,实际上捕获两者会导致您的清理命令执行两次——很可能不是您想要的。另一方面,捕获 SIGTERM 会导致程序在收到终止时不会终止。kill -9 跳过所有三个陷阱。因此,在这种情况下也不建议捕获 SIGTERM。(如果您确实出于某种原因决定捕获 SIGTERM,则您可能希望在陷阱处理程序中调用 'exit'。) (2认同)