Shell脚本中的异常处理?


Answers:


123

try/catch在bash中并没有真正的a (我假设您正在使用bash),但是您可以使用&&或实现类似的行为||

在此示例中,您要fallback_commanda_command 失败时运行(返回非零值):

a_command || fallback_command

在此示例中,您要执行second_command是否a_command 成功(返回0):

a_command && second_command

它们可以很容易地通过使用子外壳,例如,下面的命令将执行被混合在一起a_command,如果成功,则它将运行other_command,但如果a_command还是other_command失败,fallback_command将被执行:

(a_command && other_command) || fallback_command

14
奖励:如果您想要“最终”喜欢的行为,请使用no-op(在bash中:),如下所示:(a_command || : )下一行将运行,就好像没有错误发生一样a_command
BT

太棒了!节省了我很多代码。
Mrinal

并不是真的,因为finally的语义是无论异常状态如何都可以运行。
FP自由地

12

if / else结构和退出代码可以帮助您伪造其中的一些。这应该在Bash或Bourne(sh)中起作用。

if foo ; then
else
  e=$?        # return code from if
  if [ "${e}" -eq "1"]; then
    echo "Foo returned exit code 1"
  elif [ "${e}" -gt "1"]; then
    echo "Foo returned BAD exit code ${e}"
  fi
fi

1
if foo ; then else可以简化为 if ! foo ; then+1。
jlliagre 2011年

2
@jiliagre那行不通。“!foo”反转$?!从0到1和0比0
brightlancer

7
{
    # command which may fail and give an error 
} || {
   # command which should be run instead of the above failing      command
}

6
可能是better如果您向问这个问题的人解释了您发布的伪代码,而不只是他们可能不理解的一部分密码。如果孩子听不懂,那不是一个好答案。
Yokai

3

这是两个简单的bash函数,可在bash中启用事件处理

您可以将其用于基本的异常处理,如下所示:

onFoo(){
  echo "onFoo() called width arg $1!"
}  

foo(){
  [[ -f /tmp/somefile ]] || throw EXCEPTION_FOO_OCCURED "some arg"
} 

addListener EXCEPTION_FOO_OCCURED onFoo

bash不支持使用try / catch块进行异常处理,但是,您可能想尝试查看支持它的BANGSH框架(它有点像bash的jquery)。

然而,exceptionhandling没有级联的try / catch块类似于eventhandling,这可以在几乎任何与阵列支持的语言。

如果您想保持代码整洁(没有if / else冗长),我建议使用事件。

不推荐MatToufoutu推荐的建议(使用||和&&)用于函数,但对于简单命令则建议。(有关风险,请参见BashPitfalls


0

如果error_exit是接受一个参数的函数,请使用以下命令正确处理错误。如果未传递参数,则会在实际发生错误的地方使用LineNo抛出未知错误。请在实际用于生产之前进行试验-

#!/bin/bash

PROGNAME=$(basename $0)

error_exit()

{

    echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
    exit 1
}

echo "Example of error with line number and message"
error_exit "$LINENO: An error has occurred."
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.