【问题标题】:Is "exit ${?}" correct to use in bash?在 bash 中使用“exit ${?}”是否正确?
【发布时间】:2020-03-11 13:40:18
【问题描述】:

假设我编写了如下代码:

if [ ${?} -ne 0 ]; then 
    exit ${?}

这能正常工作吗? 这是正确的“语法”吗?

【问题讨论】:

标签: bash syntax exit


【解决方案1】:

您的if 语句中的[ 命令将在检查后设置$?。您需要在测试前保存原始退出状态。

some_command
es=$?
if [ "$es" -ne 0 ]; then
    exit "$es"
fi

【讨论】:

    【解决方案2】:

    语法正确,但$?if 语句中的[ ... ] 命令重置。根据定义,如果输入了if 块,那么[ ... ] 测试一定已经成功,并且$? 保证为0

    您需要将其保存在变量中。

    result=$?
    if ((result != 0)); then 
        exit "$result"
    fi
    

    另外,直接测试命令的结果比测试$? 更习惯。如果你这样做了,那么你就不会有$?改变的问题。

    if command; then
        echo success
    else
        exit   # `exit` is equivalent to `exit $?`
    fi
    

    如果你不关心成功,那么你可以使用||

    command || exit
    

    【讨论】:

    • 谢谢!这以及@chepner 的回答完全消除了我的疑虑。
    • 如果command 返回(任何)非零状态,if ! command; then exit "$?"; fi(或if ! command; then exit; fi)将以状态 0 退出。 $? 获取否定状态的值。有关问题的解释和一些解决方案,请参阅Check exit code of a program called in a while loop
    【解决方案3】:

    如果您想在出错时退出并保留命令的 EXIT 代码,您可以启用 errexit 选项:

    • 与:set -e
    • 与:set -o errexit

    见:help set | grep -F -- -e

    -e 如果命令以非零状态退出,则立即退出。

    errexit-e

    相同

    或者,您可以trap ERR 信号并使用它以错误的返回码退出。

    这将使您免于处理-e 选项的后果。

    #!/usr/bin/env bash
    
    err_handler() {
      set -- $?
      printf 'The error handler caught code #%d\n' "$1" >&2
      exit "$1"
    }
    
    trap 'err_handler' ERR
    
    create_error() {
      [ $# -ne 1 ] && return 0
      printf 'Create error #%d\n' "$1"
      return "$1"
    }
    
    create_error "$@"
    

    测试不同的错误:

    for e in 1 0 2; do ./a.sh "$e" ;echo $?; done
    Create error #1
    The error handler caught code #1
    1
    Create error #0
    0
    Create error #2
    The error handler caught code #2
    2
    

    【讨论】:

    • 使用set -o errexit (set -e) 存在限制和困难。我很乐意与他们打交道,但很多人不喜欢。请参阅BashFAQ/105 (Why doesn't set -e (or set -o errexit, or trap ERR) do what I expected?) 以获得良好、平衡的信息。
    • @pjh 我用trap添加了一个替代解决方案。
    • 您需要启用errtrace 以使ERR 陷阱触发所有将使用errexit 触发的东西。见What does set -o errtrace do in a shell script?ERR 陷阱的优点是处理程序可以打印有关错误上下文的有用信息。 (errexit 程序有时会莫名其妙地停止。)除此之外,ERR 陷阱与errexit 具有所有相同的限制和困难。需要格外小心。
    猜你喜欢
    • 2012-12-16
    • 2023-03-12
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 2014-08-13
    相关资源
    最近更新 更多