间接扩展内的参数替换

间接扩展内的参数替换

我想实现间接扩展内部的参数替换,但无法通过单个命令实现。我收到“错误替换”错误。让我知道是否有解决这个问题的聪明方法。

所以我必须使用额外的命令来解析第一个变量值,然后在间接扩展中引用它。

如何在单个命令中执行此操作,而不用额外的命令解析第一个变量值?

$ export first="hello"
$ export second_hello="finally"
$ echo ${second_${first}}
bash: ${second_${first}}: bad substitution 
$ echo ${!second_${first}}
bash: ${!second_${first}}: bad substitution
$ temp=second_${first}
$ echo ${!temp}
finally

我想避免使用额外的temp变量来获取字符串finally

答案1

在 中bash,您需要一个中间变量:

first=hello
second_hello=finally
intermediary=second_$first
printf '%s\n' "${!intermediary}"

尽管您始终可以使用以下标准方法来完成此操作eval

eval 'printf "%s\n" "${second_'"$first"'}"'

我们依次将其传递printf "%s\n" "${second_hello}"evaleval,将其解释为 shell 代码,该代码使用printf%s\n作为finally单独的参数进行调用。请注意外部和内部代码中的引号,以防止 split+glob。

在 zsh 中,相当于bash's ${!var}, 的是${(P)var},您可以通过将P参数扩展标志应用于${:-text}扩展而无需中间变量:

first=hello
second_hello=finally
printf '%s\n' ${(P)${:-second_$first}}

或者使用e参数扩展标志:

printf '%s\n' ${(e):-\$second_$first}

$first请注意,如果保证仅包含变量名中有效的字符,则所有这些方法都同样安全,否则同样不安全(引入任意命令执行漏洞),因此您可能需要清理 的值($first如果它是从外部提供给您的)脚本。

在这里,您可能需要考虑使用关联数组:

typeset -A second
second[hello]=finally
first=hello
printf '%s\n' "${second[$first]}"

但请注意,您不能export使用关联数组变量,因为环境变量只是字符串/标量。但听起来您并不希望导出任何这些变量。您只想导出您希望执行的命令“导入”的变量,就像您导出MANPATH命令man以导入它以知道在哪里查找手册页一样。

答案2

我在不使用中间变量的情况下发现了这一点。

[cloudshell-user@ip-10-0-25-104 ~]$ first=hello
[cloudshell-user@ip-10-0-25-104 ~]$ second_hello=finally
[cloudshell-user@ip-10-0-25-104 ~]$ eval echo \$second_$first
finally

相关内容