我想实现间接扩展内部的参数替换,但无法通过单个命令实现。我收到“错误替换”错误。让我知道是否有解决这个问题的聪明方法。
所以我必须使用额外的命令来解析第一个变量值,然后在间接扩展中引用它。
如何在单个命令中执行此操作,而不用额外的命令解析第一个变量值?
$ 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}"
给eval
和eval
,将其解释为 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