我正在写一个shell脚本,需要检查终端应用程序是否已安装。我想使用TRY/CATCH命令来做到这一点,除非有更整洁的方法。


当前回答

Bash中有TRY CATCH命令吗?

不。

Bash不像在许多编程语言中那样拥有那么多奢侈的东西。

bash中没有try/catch;但是,可以使用&&或||实现类似的行为。

使用| |:

如果command1失败,则command2按如下方式运行

command1 || command2

类似地,使用&&,如果command1成功,command2将运行

try/catch最接近的近似如下

{ # try

    command1 &&
    #save your output

} || { # catch
    # save log for exception 
}

此外,bash还包含一些错误处理机制

set -e

如果任何简单的命令失败,它将停止脚本。

还有为什么不是if…else。它是你最好的朋友。

其他回答

借用肖恩·梅奥的回答,你可以这样做

function check {
EXITCODE=$?
if [ "$EXITCODE" -ne "0" ]; then
    #this is the catch part
    echo "uh oh"
    exit $EXITCODE
fi
}

YOUR COMMAND HERE
check
YOUR COMMAND HERE
check
YOUR COMMAND HERE
check
YOUR COMMAND HERE
check

效果很好

你可以:

#!/bin/bash
if <command> ; then # TRY
    <do-whatever-you-want>
else # CATCH
    echo 'Exception'
    <do-whatever-you-want>
fi

正如大家所说,bash没有适当的语言支持的try/catch语法。您可以使用-e参数启动bash,或者在脚本中使用set -e来中止整个bash进程,如果任何命令有非零退出码的话。(你也可以设置+e来临时允许失败的命令。)

因此,模拟try/catch块的一种技术是在启用-e的情况下启动子进程来完成工作。然后在主进程中,检查子进程的返回码。

Bash支持heredoc字符串,因此不需要编写两个单独的文件来处理这个问题。在下面的示例中,TRY heredoc将在单独的bash实例中运行,并启用了-e,因此如果任何命令返回非零退出码,子进程将崩溃。然后,回到主进程,我们可以检查返回代码以处理一个catch块。

#!/bin/bash

set +e
bash -e <<TRY
  echo hello
  cd /does/not/exist
  echo world
TRY
if [ $? -ne 0 ]; then
  echo caught exception
fi

它不是一个适当的语言支持的try/catch块,但它可能会为您带来类似的体验。

Bash不会在检测到错误状态时中止正在运行的执行(除非您设置了-e标志)。提供try/catch的编程语言这样做是为了抑制由于这种特殊情况而产生的“保释”(因此通常称为“异常”)。

相反,在bash中,只有有问题的命令将退出,退出码大于0,表示错误状态。当然,您可以检查这一点,但由于没有任何自动保释,因此try/catch没有意义。它只是缺乏背景。

然而,你可以通过使用子壳来模拟一个保释,它可以在你决定的点终止:

(
  echo "Do one thing"
  echo "Do another thing"
  if some_condition
  then
    exit 3  # <-- this is our simulated bailing out
  fi
  echo "Do yet another thing"
  echo "And do a last thing"
)   # <-- here we arrive after the simulated bailing out, and $? will be 3 (exit code)
if [ $? = 3 ]
then
  echo "Bail out detected"
fi

而不是some_condition的if你也可以尝试一个命令,如果它失败(退出码大于0),保释:

(
  echo "Do one thing"
  echo "Do another thing"
  some_command || exit 3
  echo "Do yet another thing"
  echo "And do a last thing"
)
...

不幸的是,使用这种技术只能使用255个不同的退出码(1..255),而且不能使用像样的异常对象。

如果你需要更多的信息来传递模拟异常,你可以使用subshell的stdout,但这有点复杂,可能是另一个问题;-)

使用上面提到的-e标志,你甚至可以剥离显式的退出语句:

(
  set -e
  echo "Do one thing"
  echo "Do another thing"
  some_command
  echo "Do yet another thing"
  echo "And do a last thing"
)
...

你有陷阱http://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html,这是不一样的,但你可以使用其他技术来达到这个目的