4

注意:这不是In bash的副本,是否有 die "error msg" 的等价物,如本文末尾所示。

考虑shell函数

foo () {
    echo "testing..." 1>&2
    return 1
    echo "should never reach this point" 1>&2
}

下面显示了foo的预期行为:

% foo || echo $?
testing...
1

我想将前行中显示的功能封装foo在一个函数die中,以便可以将定义foo简化为

foo () {
    die 1 "testing..."
    echo "should never reach this point" 1>&2
}

...同时仍保留其原始行为。

我的兴趣主要是zsh,但也会对适合bash和/或/bin/sh脚本的答案感兴趣,如果它们不同的话。


顺便说一句,这不起作用:

die () {
    local exit_code=$1
    shift
    echo "$*" 1>&2
    exit $exit_code
}

如果从命令行运行一个foo使用 this的版​​本die,结果将是杀死一个人当前的 shell(至少这是我尝试类似的东西时得到的结果)。这就是为什么这个问题不是In bash, is there an equivalent of die "error msg"的重复。无论如何,其他问题的答案不会满足我在这里的要求。

4

2 回答 2

1

严格来说,我不认为你想要什么是可能的。你不能简单地通过调用另一个函数从一个函数返回。不过,这可能接近您想要的:

die () {
    echo "${*:2}" 1>&2
    return $1
}

foo () (      # Parentheses, not braces, to enclose the body
    set -e
    die 1 "testing..."
    echo "Shouldn't reach here" 1>&2
)

die返回状态为 1 时,set -e会导致当前 shell 退出。但是, 的主体foo启动了一个新的子shell,所以这就是退出的内容,将控制权返回给调用foo. 但是,有两个明显的问题:

  1. set -e; die...不短于echo...; return 1
  2. 制作foo子外壳的主体将防止调用者看到该函数中设置的任何变量。
于 2013-04-04T21:16:49.000 回答
0

从 zsh 4.3.4 开始,您可以使用 throw/catch 语法。我发现它比老式的 'set -e' 或 exit 进行错误处理的问题要少得多。只要确保你执行“autoload -U throw catch”来访问它们。查看“man zshcontrib”了解详细信息。

于 2013-12-01T00:01:56.477 回答