如何定义一个“die”shell函数?

kjo*_*kjo 5 shell zsh

注意:这不是In bash, is there a equal to die "error msg" 的重复,如本文末尾所示。

考虑 shell 函数

foo () {
    echo "testing..." 1>&2
    return 1
    echo "should never reach this point" 1>&2
}
Run Code Online (Sandbox Code Playgroud)

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

% foo || echo $?
testing...
1
Run Code Online (Sandbox Code Playgroud)

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

foo () {
    die 1 "testing..."
    echo "should never reach this point" 1>&2
}
Run Code Online (Sandbox Code Playgroud)

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

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


顺便说一句,这行不通:

die () {
    local exit_code=$1
    shift
    echo "$*" 1>&2
    exit $exit_code
}
Run Code Online (Sandbox Code Playgroud)

如果从命令行运行foo使用 this的版die​​本,结果将是终止当前的 shell(至少这是我尝试类似操作时得到的结果)。这就是为什么这个问题不是In bash, is there a equal to die "error msg"的重复问题。无论如何,其他问题的答案不能满足我的要求。

che*_*ner 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
)
Run Code Online (Sandbox Code Playgroud)

die以状态 1 返回时,会set -e导致当前 shell 退出。然而, 的主体foo启动了一个新的子 shell,因此这就是退出的内容,将控制权返回给调用 的 shell foo。然而,存在两个突出的问题:

  1. set -e; die...不短于echo...; return 1
  2. 制作子 shell 的主体foo将阻止调用者看到该函数中设置的任何变量。