使用 $ 的最佳实践?在bash中?

使用 $ 的最佳实践?在bash中?

当我读到这篇文章时回答$?我想到了另一个问题。

有没有关于如何使用 $ 的最佳实践?在bash中?


让我们举个例子:

我们有一个线性脚本,我们想知道所有命令都执行正常。您认为可以调用一个小函数(我们称之为“did_it_work”)来检查错误代码,如果不是则中断。

#!/bin/bash 

function did_it_work {
    code=$1
    if [ "$code" -ne "0" ]
    then
        echo "Error failure: code $code "
        exit 1
    fi
}

dir=some/path

mkdir -p $dir
did_it_work $? 

cd $dir
did_it_work $? 

run_some_command
did_it_work $? 

这种方法当然意味着我必须手动解决问题(如果有)并重新运行脚本。

您认为这是一个好主意还是有其他最佳实践可以做到这一点?

/谢谢

答案1

一种常见的方式是:

die() {
    IFS=' ' # make sure "$*" is joined with spaces

    # output the arguments if any on stderr:
    [ "$#" -eq 0 ] || printf '%s\n' "$*" 1>&2
    exit 1
}

然后你像这样使用它:

mkdir -p some/path || die "mkdir failed with status $?"

或者,如果您希望它包含退出状态,您可以将其更改为:

die() {
    last_exit_status=$?
    IFS=' '
    printf '%s\n' "FATAL ERROR: $* (status $last_exit_status)" 1>&2
    exit 1
}

然后使用它会更容易一些:

mkdir -p some/path || die "mkdir failed"

当它失败时,mkdir可能已经发出错误消息,因此第二个可能被视为多余,您可以这样做:

mkdir -p some/path || exit   # with the same (failing) exit status as mkdir's
mkdir -p some/path || exit 1 # with exit status 1 always

(或者使用上面的第一个变体die而不带参数)

以防万一您command1 || command2以前没有见过,它会运行command1,如果command1失败,它也会运行command2

所以你可以像“创建目录或死亡”一样阅读它。

你的例子看起来像:

mkdir -p some/path || die "mkdir failed"
cd some/path || die "cd failed"
some_command || die "some_command failed"

或者你可以dies进一步靠右对齐,这样主要代码就更明显了。

mkdir -p some/path         || die "mkdir failed"
cd some/path               || die "cd failed"
some_command               || die "some_command failed"

或者当命令行很长时在下面一行:

mkdir -p some/path ||
  die "mkdir failed"

cd some/path ||
  die "cd failed"

some_command ||
  die "some_command failed"

另外,如果您要some/path多次使用该名称,请将其存储在变量中,这样您就不必不断键入它,并且可以在需要时轻松更改它。当将变量参数传递给命令时,请确保使用选项--分隔符,这样如果参数以 开头,则不会将其视为选项-

dir=some/path
mkdir -p -- "$dir"         || die "Cannot make $dir"
cd -P -- "$dir"            || die "Cannot cd to $dir"
some_command               || die "Cannot run some_command"

答案2

你可以像这样重写你的代码:

#!/bin/bash
function try {
    "$@"
    code=$?
    if [ $code -ne 0 ]
    then
        echo "$1 did not work: exit status $code"
        exit 1
    fi
}

try mkdir -p some/path
try cd some/path
try run_some_command

如果您实际上不需要记录错误代码,而只需要记录命令是否成功,则可以try()进一步缩短,如下所示:

function try {
    if ! "$@"
    then
        echo "$1 did not work"
        exit 1
    fi
}

答案3

如果您确实想exit解决错误并且正在使用 Bash,那么您还应该考虑set -e.从help set

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

这当然不会为您提供 did_it_work() 函数的灵活性,但这是一种确保 bash 脚本在出现错误时停止的简单方法,而无需向新函数添加大量调用。

相关内容