【问题标题】:Why is my bash function returning an unexpected return code?为什么我的 bash 函数返回意外的返回码?
【发布时间】:2013-12-07 07:16:15
【问题描述】:

我一直在创建一个小型 bash 函数库,以将一些更神秘的 bash 语法结构封装到我可以快速使用和引用的例程中。但是对于其中一些,我的函数遇到了意外的返回码。下面的“is_undefined”函数就是这样一个例子。谁能解释我得到的结果? (也在下面提供。)

#!/bin/bash

is_undefined ()
{
  # aka "unset" (not to be confused with "set to nothing")
  # http://stackoverflow.com/questions/874389/bash-test-for-a-variable-unset-using-a-function
  [ -z ${1+x} ]
}

if [ -z ${UNDEFINED+x} ]; then
  echo "inline method reports that \$UNDEFINED is undefined"
fi

if is_undefined UNDEFINED; then
  echo "is_undefined() reports that \$UNDEFINED is undefined"
else
  echo "is_undefined() reports that \$UNDEFINED is defined"
fi

DEFINED=
if is_undefined DEFINED; then
  echo "is_undefined() reports that \$DEFINED is undefined"
else
  echo "is_undefined() reports that \$DEFINED is defined"
fi

令人惊讶的结果是:

$ ./test.sh
inline method reports that $UNDEFINED is undefined
is_undefined() reports that $UNDEFINED is defined
is_undefined() reports that $DEFINED is defined

【问题讨论】:

  • 添加 set -vx 以查看何时处理的方式/内容。祝你好运。
  • 最新版本的bash 有一个-v 运算符来测试是否设置了变量。 [[ -v foo ]] 仅在未设置 foo 时成功;如果 foo 设置为空字符串,则失败。
  • 关于 -v:几个月前我设法将它加入到我的代码中,但忘记记录参考。我昨晚删除了它,因为我没有在我的 bash 书中找到它,并且谷歌搜索它没有产生任何结果。我想我一定是想象出来的……我想不是! :)
  • 哦,我对-v的描述完全倒退了:(-v foofoo 设置时为真,否则为假。在4.2中引入。

标签: bash function return-code


【解决方案1】:

is_undefined 内部,您正在测试$1,而不是${UNDEFINED},为此您需要像这样抛出变量间接

is_undefined () {
    [ -z "${!1+x}" ]
}

但是,这是 bashism,不符合 posix。对于 posix 兼容,您将需要

is_undefined () {
    eval "[ -z \${$1+x} ]"
}

【讨论】:

    【解决方案2】:

    is_undefined UDEFINED 返回 true,因为 is_undefined 内部的测试不测试 UNDEFINED$1$1 已定义 。它的值是UNDEFINED

    因此,只要您提供参数,您的函数就应该始终返回 true。唯一一次它会返回 false,应该是当你不带参数调用它时

    is_undefined
    

    要获取is_undefined测试实际变量,可以使用带感叹号!的变量间接寻址,见Shell Parameter Expansion

    is_undefined ()
    {
      # aka "unset" (not to be confused with "set to nothing")
      # http://stackoverflow.com/questions/874389/bash-test-for-a-variable-unset-using-a-function
      [ -z "${!1+x}" ]
    }
    

    【讨论】:

    • 这是有道理的。但是我必须怎么做才能在 is_undefined() 内的那个表达式中取消引用 $1 以获得我想要的行为?
    • 您可以使用变量间接,请参阅更新的答案。
    • 谢谢! (Meta:我不确定是接受你的回答,还是接受@yaccz 的回答。他在你之前提供了变量间接组件,但你的两个回答都同样有帮助。在这种情况下,礼仪是什么?)
    • 礼仪什么的我都不懂,最终还是看你自己。无论哪种情况,如果您接受他的回答,我都不会介意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多