如何定义“死”shell函数?

时间:2013-04-02 18:38:27

标签: shell zsh

注意:In bash, is there an equivalent of 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的{​​{1}}版本,结果将是杀死当前的shell(至少这是我尝试类似的时候得到的结果)。这就是为什么这个问题In bash, is there an equivalent of die "error msg"的副本。无论如何,其他问题的答案将无法满足我的要求。

2 个答案:

答案 0 :(得分: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的shell。但是,有两个明显的问题:

  1. set -e; die...不短于echo...; return 1
  2. 使foo的主体成为子shell将阻止该函数中设置的任何变量对调用者可见。

答案 1 :(得分:0)

从zsh 4.3.4开始,您可以使用throw / catch语法。我发现它比旧学校'set -e'或出错处理错误要小得多。只要确保你执行“autoload -U throw catch”即可访问它们。查看“man zshcontrib”了解详情。