0

我有一个通过环境变量提供配置的脚本。由于配置是手动编辑的,因此可能会将从未使用过的拼写错误和变量添加到配置中。

有没有办法获取有关变量的元数据,如果未读取变量,则允许执行后步骤发出警告?

可接受的答案包括,

  • 一种计算变量被读取次数的方法
  • 如果已读取 var,则为 true 的标志
  • 一种确定上次访问 var 时间的方法

上面可能没有列出其他可接受的答案。

出现这个问题的部分原因是 Bash 默认是无类型的。

4

1 回答 1

2

您的帖子中有两个问题。第一个问题:

如何检测是否已读取 Bash 环境变量?

尽管没有一个可接受的答案包括我的,但为了其他人的利益,我会回答第一个问题:

无论如何,除了修改 Bash。

你当然可以拒绝它。

第二个问题:

有没有办法获取有关变量的元数据,如果未读取变量,则允许执行后步骤发出警告?

问这个问题没有多大意义,因为可能的答案不包括在可接受的答案列表中。但无论如何我都会回答:

不,除非 Bash 被修改。

现在,即使您可能对我的意见不感兴趣,因为它不在可接受的答案列表中,但无论如何我都会将其作为练习呈现给我,也许对其他人有用。

首先,在这种情况下发出警告大多是无用的,尤其是在执行之后。无论在提供参数时犯了什么错误,到那时它们已经生效,无论是损坏的数据还是只是时间丢失。此外,如果大多数人认为脚本工作的结果是好的,他们不会注意到警告。他们以后可能会发现自己错了,但可能为时已晚。

如果您要验证参数,请在执行之前执行此操作,如果错误则中止。

确保环境变量名称中没有拼写错误的一种方法是为它们创建一个命名空间,方法是要求它们的名称以固定字符串作为前缀,然后验证具有该前缀的所有变量名称对于程序都是已知的。但是,这并不能防止前缀字符串中的拼写错误。尽管如此,据我所知,没有其他程序可以做到这一点,这可能意味着几乎没有人期望程序会出现这种行为。这违反了“最不意外的规则”,我会说,这是不必要的。

我建议根本不验证环境变量名称。如果你的程序有复杂的配置,需要验证,不要把它放到环境中。将其放入配置文件中,不会与其他程序共享。

一种简单的方法是使配置文件成为设置一堆变量的源 shell 脚本。这将允许简单的“解析”(正如 Bash 所做的那样)和验证​​。为了验证它,在一个子shell中获取它(因此主shell不受影响),输出设置的变量名称,过滤掉在获取之前设置的变量,然后将它们与已知配置变量名称列表进行比较。

像这样的东西:

function list_vars() {
    declare -p | awk -F'[ =]' '/^declare/ {print $3}'
}

function unset_vars() {
    while read v; do
        unset "$v" 2>/dev/null;
    done < <(list_vars);
}

declare -a CONF_VAR_NAMES=(FOO BAR BAZ)

extra_vars=`
    (
        # Unset all variables that can be unset (and thus set)
        unset_vars
        # List variables set after sourcing configuration
        (. conf_file.sh; list_vars) |
            # Remove variables set before sourcing
            grep -v -F -f <(list_vars)
    ) |
        # Remove known variables
        grep -v -F -f <(IFS=$'\n'; echo "${CONF_VAR_NAMES[*]}")
`

if [ -n "$extra_vars" ]; then
    echo "Unknown variables set by configuration script: $extra_vars" >&2
    exit 1
fi

不过,您可能需要对 PATH 和其他重要变量进行特殊处理。验证时,在采购之前简单地将所有变量设置为只读可能是个好主意。

于 2013-05-10T13:23:05.993 回答