【问题标题】:Pass variable name into function to test both existence and non-empty将变量名传递给函数以测试存在和非空
【发布时间】:2020-05-24 01:11:49
【问题描述】:

A) 我是 bash 新手

B) 我的 bash 脚本来源一个(用户可编辑的)配置脚本,我想在其中使用一个函数来测试变量的存在性和非空性。

在我的脚本中,每一行都有 21 行(变量):

# check if constant exists
${_CONFIG_VERSION+"false"} && exitLogged "" "Constant _CONFIG_VERSION not set in ${_CONFIG_FILE}"
${_HOSTNAME+"false"} && exitLogged "" "Constant _HOSTNAME not set in ${_CONFIG_FILE}"
${_SYSTEM_NAME+"false"} && exitLogged "" "Constant _SYSTEM_NAME not set in ${_CONFIG_FILE}"
${_SP_LINK_CFG_FILENAME+"false"} && exitLogged "" "Constant _SP_LINK_CFG_FILENAME not set in ${_CONFIG_FILE}"
...

# check if constant has a value
if [[ -z "${_CONFIG_VERSION}" ]]; then exitLogged "" "Constant _CONFIG_VERSION not set in ${_CONFIG_FILE}"; fi
if [[ -z "${_HOSTNAME}" ]]; then exitLogged "" "Constant _HOSTNAME not set in ${_CONFIG_FILE}"; fi
if [[ -z "${_SYSTEM_NAME}" ]]; then exitLogged "" "Constant _SYSTEM_NAME not set in ${_CONFIG_FILE}"; fi
if [[ -z "${_SP_LINK_CFG_FILENAME}" ]]; then exitLogged "" "Constant _SP_LINK_CFG_FILENAME not set in ${_CONFIG_FILE}"; fi
...

...但想这样做:

checkIfExistAndNonEmpty _CONFIG_VERSION
checkIfExistAndNonEmpty _HOSTNAME
checkIfExistAndNonEmpty _SYSTEM_NAME
checkIfExistAndNonEmpty _SP_LINK_CFG_FILENAME

... 伪代码中的函数如下:

function checkIfExistAndNonEmpty() {
    arg1=${1}
    "$"{$arg1+"false"} && exitLogged "" "Constant $arg1 not set in ${_CONFIG_FILE}"        
    if [[ -z "${arg1}" ]]; then ...; fi
}

exitLogged() 记录传入和退出的两个参数($LINENO $msg)。

这样的函数“checkIfExistAndNonEmpty()”是否可行?

意图是传递变量名;将其重建为一个变量,我可以测试它的存在性和非空性。

通常如果有重复相同的事情然后推到一个函数中......但我可能会要求一些不可能的东西。

[编辑 1] 我看过这个...但不是很明白...

function checkIfExistAndNonEmpty() {
    suffix=$1
    echo "suffix:$suffix"
    declare prefix_$suffix=$1
    # ...and then...
    varname=prefix_$suffix
    echo "varname:${!varname}"
    echo "---"
}

[编辑 2] 仔细想想,我可能是想太多问题的解决方案了?! 也许是一个简单的

if [[ -z "${_variable}" ]]; then echo "Variable is not specified."; fi

... 可以,因为“未指定”可能意味着“它是空的”和“不存在”。

所以,除非有聪明的头脑可以启发我,否则我会按照上面的想法进行。 :)

【问题讨论】:

  • "$"{$arg1+"false"} 是一个错误,试试shellcheck.net
  • 是的...为什么我在“伪代码”中说... :)
  • 你想使用nameref(又名local -n ...);请参阅此question 和此question 中的示例代码;虽然这些问题与数组有关,但主要步骤是相同的​​,例如,'local -n arg1=${1}`
  • 我看了一下,误解似乎是我想要变量名。是的,我想要变量名和变量本身(检查是否存在)。因此,传递名称然后检查变量是否存在的想法;这意味着我必须将名称转换为实际变量。

标签: bash


【解决方案1】:

可以将问题改写为以下内容:在代码的特定点,脚本必须检查变量列表是否已设置为非空值。

考虑选择实现这一点,无需大量复制/粘贴:使用 bash 内置 :?,或使用自定义迭代

使用 bash :? 操作符,你会得到 bash 标准错误信息 + 退出状态:

  • 消息“bash: VARIABLE: 参数为空或未设置
  • 1的退出状态

每行可以指定多个测试。

: ${_CONFIG_VERSION:?}
: ${_HOSTNAME:?}
: ${_SYSTEM_NAME:?} ${_SP_LINK_CFG_FILENAME:?}

如果对控制错误消息很重要,或者有自定义错误处理

v_list=( _CONFIG_VERSION _HOSTNAME _SYSTEM_NAME ...)
for v in "${v_list[@]}" ; do
    # Check if the variable expand to non-empty
    if [ ! -n "${!v}" ] ; then
       exitLogged "Constant $v not set in ${_CONFIG_FILE}"
    fi
done

【讨论】:

  • 是的,这无疑简化了非空检查;谢谢 :) 但没有澄清,我是否真的可以将变量名转回变量以检查它的存在。
  • 刚刚实现,很好,并且认为“${v[@]}”应该是“${v_list[@]}”
猜你喜欢
  • 2014-08-13
  • 2017-07-21
  • 2016-11-29
  • 2017-04-20
  • 1970-01-01
  • 2015-02-19
  • 2019-07-22
  • 1970-01-01
  • 2020-07-28
相关资源
最近更新 更多