【问题标题】:Bash function to check if a given variable is set用于检查是否设置了给定变量的 Bash 函数
【发布时间】:2017-10-28 11:59:42
【问题描述】:

正如this answer 中所述,检查是否在 bash 中设置了变量的“正确”方法如下所示:

if [ -z ${var+x} ]; then
    echo "var is unset"
else
    echo "var is set to '$var'"
fi

我感兴趣的是如何将其提取到一个可重复用于不同变量的函数中。

到目前为止,我能做到的最好的是:

is_set() {
  local test_start='[ ! -z ${'
  local test_end='+x} ]'
  local tester=$test_start$1$test_end

  eval $tester
}

这似乎有效,但有没有更好的方法不求助于eval

【问题讨论】:

  • 创建一个函数来测试是否设置了变量似乎不是一个好主意。您将硬编码要检查的变量(这没有意义),不推荐使用eval,尤其是当您不能绝对确定变量内容时,或者将要检查的变量值作为参数传递带您回到 [[ -z $1 ]] 测试开始。
  • 这里有一个微妙的区别:如果var 要么 为空字符串 未设置,[[ -z $var ]] 返回 true。 [[ -z ${var+x} ]] 严格测试未设置。
  • @John1024: 很好!
  • @DavidC.Rankin 我想写一个函数来使代码自我记录,因为语法非常神秘。不过,考虑到复杂性,我同意你的观点,这让我思考了记录你正在编写的域逻辑和记录语言本身的工作方式之间的区别。由于语言在这里阻碍了我的努力,我将坚持使用最简单的方法,而不是尝试将其包装在函数中。
  • 我不能 100% 确定你会在 bash 3 中得到相同的结果,但你可以使用 ! 运算符 isunset() { [[ -z ${!1+x} ]];} 间接检查变量,然后你可以使用 if isunset var; then echo var is not set跨度>

标签: bash


【解决方案1】:

在 Bash 中,您可以使用 [[ -v var ]]。不需要函数或复杂的方案。

来自手册页:

   -v varname
          True if the shell variable varname is set (has been assigned a value).

前 2 个命令序列打印 ok:

[[ -v PATH ]] && echo ok

var="" ; [[ -v var ]] && echo ok

unset var ; [[ -v var ]] && echo ok

【讨论】:

  • 我猜这是在比我正在运行的更新版本的 Bash 中添加的?我得到bash: conditional binary operator expected,但我使用的是 OSX (3.2.57) 附带的 Bash 版本。无论如何我应该升级,但我正在编写这个脚本来帮助同事设置他们的开发环境的一部分,所以可移植性是一个问题。
  • 然后是像[[ -z ${var+x} ]] 这样更简洁的方式,正如前面所指出的,这是要走的路。它在 Bash 3 中有效吗?在函数中运行eval 进行简单检查是丑陋的,而且是自找麻烦。
  • 是的,[[ -z ${var+x} ]] 方法在 Bash 3 中有效。我会坚持下去。很高兴知道 -v 已添加,谢谢!
【解决方案2】:

使用[[ ... ]],您可以简单地执行此操作(不需要双引号):

[[ $var ]] && echo "var is set"
[[ $var ]] || echo "var is not set or it holds an empty string"

如果你真的想要一个函数,那么我们可以写单行:

is_empty()     { ! [[ $1 ]]; } # check if not set or set to empty string
is_not_empty() {   [[ $1 ]]; } # check if set to a non-empty string

var="apple"; is_not_empty "$var" && echo "var is not empty" # shows "var is not empty"
var=""     ; is_empty "$var"     && echo "var is empty"     # shows "var is empty"
unset var  ; is_empty "$var"     && echo "var is empty"     # shows "var is empty"
var="apple"; is_empty "$var"     || echo "var is not empty" # shows "var is not empty"

最后,is_unsetis_set 可以实现将$1 视为变量的名称:

is_unset() {   [[ -z "${!1+x}" ]]; }           # use indirection to inspect variable passed through $1 is unset
is_set()   { ! [[ -z "${!1+x}" ]]; }           # check if set, even to an empty string

unset var; is_unset var && echo "var is unset" # shows "var is unset"
var=""   ; is_set var   && echo "var is set"   # shows "var is set"
var="OK" ; is_set var   && echo "var is set"   # shows "var is set"

相关

【讨论】:

    猜你喜欢
    • 2011-04-05
    • 2014-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    相关资源
    最近更新 更多