【问题标题】:How to test if a variable exists and has been initialized如何测试变量是否存在并已初始化
【发布时间】:2014-11-24 15:14:32
【问题描述】:

我必须执行一个函数,该函数必须测试一个变量是否已在 Bash 中正确定义,并且必须使用其关联值。

例如,这些变量在脚本顶部初始化。

#!/bin/bash

var1_ID=0x04
var2_ID=0x05
var3_ID=0x06
var4_ID=0x09

我想调用名为test的脚本如下:

./test var1

目前实现的功能是:

function Get()
{
     if [ $1"_ID" != "" ]; then
         echo "here"
         echo $(($1_ID))
     else
         exit 0
     fi
}

我不明白为什么即使我输入./test toto 或其他内容,我也会获得here。

是否需要使用特定的命令,例如grep?

【问题讨论】:

标签: bash shell variables


【解决方案1】:

您可能想使用间接扩展:${!variable},然后-n 来检查它是否已定义:

间接扩展在于用另一个变量调用一个变量。也就是说,由于变量名可能会发生变化,我们不说$a,而是说${!var} 和var=a。

$ cat a
var1_ID=0x04
var2_ID=0x05
var3_ID=0x06
var4_ID=0x09

for i in {1..5}; do
   v="var${i}_ID"
   if [ -n "${!v}" ]; then             # <-- this expands to varX_ID
      echo "$v set to value: ${!v}"
   else
      echo "$v not set"
   fi
done

如果我们执行,我们得到:

$ ./a
var1_ID set to value: 0x04
var2_ID set to value: 0x05
var3_ID set to value: 0x06
var4_ID set to value: 0x09
var5_ID not set

来自man test:

-n 字符串

STRING 的长度不为零

【讨论】:

  • 谢谢你费多基。但是,我不太理解。 ${!v} 是什么意思?
  • 这称为间接扩展。它包括用另一个变量调用一个变量。也就是说,由于变量名可能会发生变化,我们不说$a,而是说${!var} 和var=a。你可以在bash: indirect expansion, please explain?阅读更多内容。
  • 真的很好!非常感谢
  • 而且,正如 fedorqui 通过a related article 指出的那样,您可以使用扩展${variable+string} 来测试是否设置。
【解决方案2】:

使用参数展开:

: ${var:?}

如果空字符串是有效值,则删除冒号(即,您只想测试定义性)。

: ${var?}

如果您不希望脚本在问题上停止,可以使用

if [[ ${var:+1} ]] ; then
    # OK...
else
    echo Variable empty or not defined. >&2
fi

记录在man bash中的参数扩展下:

当不执行子字符串扩展时,使用下面记录的形式(例如,:-),bash 测试未设置或为空的参数。省略冒号只会导致测试 对于未设置的参数。

${parameter:?word}

如果为 Null 或未设置,则显示错误。如果参数为空或未设置,则扩展 word(或如果 word 不存在,则显示该效果的消息)被写入标准错误,并且 shell(如果它不是交互式的)退出。否则,值 参数被替换。

${parameter:+word}

使用替代值。如果参数为null或未设置,则不替换任何内容,否则替换单词的扩展。

【讨论】:

  • 您能否为操作员:?、? 和:+1(或其他任何名称)添加一些(特定)文档引用? (但没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的。)
  • 更新了相关部分。
【解决方案3】:

在bash 4.2 中,您可以在条件表达式中使用-v 运算符来测试是否设置了具有给定名称的变量。

if [[ -v ${1}_ID ]]; then
    echo "${1}_ID is set"
    foo=${1}_ID
    echo "${!foo}"
fi

你仍然需要间接参数扩展来获取值。

在bash 4.3 中,您可以使用命名引用来更轻松地使用它。

declare -n param=${1}_ID
if [[ -v param ]]; then
    echo "${1}_ID"
    echo "$param"
fi

(param 的行为将与它引用的变量完全一样。我不知道是否有一种简单的方法,除了解析 declare -p param 的输出,来获取它引用的变量的名称。)

【讨论】:

  • 什么是“_ID”?大会?神奇的价值?也许在答案中解释一下?
  • 这只是 OP 使用的变量名的常量部分。假设$1 的值类似于var1、var2 等。var1 和_ID 一起形成var1_ID,这就是我们正在测试其存在的变量的名称。跨度>
猜你喜欢
  • 2022-07-05
  • 2022-12-03
  • 2011-10-12
  • 2016-10-03
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多