【问题标题】:What is the best way to write a wrapper function that runs commands and logs their exit code编写运行命令并记录其退出代码的包装函数的最佳方法是什么
【发布时间】:2008-12-16 17:55:40
【问题描述】:

我目前使用这个函数来包装正在执行的命令并记录它们的执行,并返回代码,并在返回代码非零的情况下退出。

但这显然是有问题的,它会进行双重插值,使带有单引号或双引号的命令破坏脚本。

你能推荐一个更好的方法吗?

函数如下:

do_cmd()
{
    eval $*
    if [[ $? -eq 0 ]]
    then
        echo "Successfully ran [ $1 ]"
    else
        echo "Error: Command [ $1 ] returned $?"
        exit $?
    fi
}

【问题讨论】:

    标签: bash unix shell


    【解决方案1】:
    "$@"
    

    来自http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters

    @

    从一开始扩展到位置参数。当。。。的时候 扩展发生在双引号内,每个参数扩展为 单独的词。也就是说,"$@" 等价于 "$1" "$2" .... 如果 双引号扩展出现在一个单词中,扩展 第一个参数与原始的开始部分连接 词,最后一个参数的扩展与最后一个连接 原词的一部分。当没有位置参数时, "$@" 和 $@ 扩展为空(即,它们被删除)。

    这意味着参数中的空格被正确地重新引用。

    do_cmd()
    {
        "$@"
        ret=$?
        if [[ $ret -eq 0 ]]
        then
            echo "Successfully ran [ $@ ]"
        else
            echo "Error: Command [ $@ ] returned $ret"
            exit $ret
        fi
    }
    

    【讨论】:

    • 当然,cmd; if [[ $? -eq 0 ]]; then stuff 写成if cmd; then stuff 更惯用。
    • 但是代码应该稍后使用 $ret,所以保存它更清楚恕我直言。
    • 我使用这个,在stackoverflow.com/a/15383353/1172302 之后稍作修改以捕获在子 shell 中运行的命令的退出状态。
    【解决方案2】:

    除了"$@" Douglas 所说的,我会使用

    return $?
    

    而不是exit。它会退出你的 shell 而不是从函数返回。如果您想在出现问题时退出 shell,您可以在调用者中执行此操作:

    do_cmd false i will fail executing || exit
    # commands in a row. exit as soon as the first fails
    do_cmd one && do_cmd && two && do_cmd three || exit
    

    (这样,您可以处理失败,然后优雅地退出)。

    【讨论】:

      猜你喜欢
      • 2010-10-06
      • 2014-06-14
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 2010-12-31
      • 1970-01-01
      相关资源
      最近更新 更多