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


当前回答

假设终端应用名为'app'(你希望它在你的$PATH中):

if [[ ! `which app` ]]; then
    # run code if app not installed
else
    # run code if app is installed
fi

其他回答

我使用的方法是这样的:

YOUR COMMAND HERE
EXITCODE=$?
if [ "$EXITCODE" -ne "0" ]; then
    #this is the catch part
    echo "uh oh"
    exit $EXITCODE
fi

这只是检查命令的退出码,并将其与零进行比较 (表示命令运行成功)

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

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

效果很好

正如大家所说,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块,但它可能会为您带来类似的体验。

你可以使用trap:

try {block A} catch {block B} finally {block C}

翻译:

(
  set -Ee
  function _catch {
    block B
    exit 0  # optional; use if you don't want to propagate (rethrow) error to outer shell
  }
  function _finally {
    block C
  }
  trap _catch ERR
  trap _finally EXIT
  block A
)

你可以:

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