![将变量值和字符串组合起来形成另一个变量](https://linux22.com/image/127968/%E5%B0%86%E5%8F%98%E9%87%8F%E5%80%BC%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%BB%84%E5%90%88%E8%B5%B7%E6%9D%A5%E5%BD%A2%E6%88%90%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F.png)
我想从变量引用 bash 变量而不使用:
echo "${!VARNAME}"
有任何想法吗?由于我想动态使用该变量并且存在许多此类引用,因此我无法将它们声明为另一个变量并使用它。
例子:
var1=host
${var1}_file ----> host_file is another variable that i want to call in a command.
答案1
我真的不明白为什么你不想使用变量间接,除非你正在编写sh
(不是bash
)脚本。
正如已经提到的,eval
它会起作用,但通常会受到反对,因为它的使用可能存在危险,特别是在没有仔细清理的情况下评估用户提供的数据时。
实现相同效果的另一种方法是使用名称引用变量(bash
自版本 4.3 起可用)。
var1=host
declare -n nameref="${var1}_file"
nameref="something something"
printf '%s\n' "$host_file"
这将输出字符串something something
。使用typeset -n
代替declare -n
可以使其在 和bash
中工作ksh93
。
答案2
如果您的变量被命名为某些专有名称和相关属性的组合,您可能应该使用关联数组。假设您有 Bash 4.x、ksh 或 zsh。看到页或者其他在 BashGuide 上。 (实际上,像 C 中那样的结构会很好,但用 Bash 却无法真正实现这一点。)
也就是说,要存储主机/集群的 URL 和端口oregon
,arizona
不要创建四个变量arizona_url
, arizona_port
, oregon_url
, oregon_port
,而是像这样:
typeset -A urls ports
urls[oregon]="http://..."
urls[arizona]="http://..."
ports[oregon]=1234
ports[arizona]=2345
然后将它们与等一起使用"${urls[$hostname1]}"
。"${ports[$hostname]}"
答案3
根据之前的答案,您可以使用 eval 来实现此目的。
eval [arg ...] 读取参数并将其连接在一起形成单个命令。然后 shell 读取并执行该命令,其退出状态作为 eval 的值返回。如果没有 args,或者只有 null 参数,eval 返回 0。(来自 bash 手册页)
然而,这是一种不好的编程习惯,您需要非常了解并尽可能少地使用。通常可以避免使用它,以获得更优雅、更不易出错且更易于调试的东西。
var1=host
eval echo ${var1}_file # print contents of $host_file
答案4
它也适用于数组!
下面是 @Kusalananda 方法的概括,但是使用数组......
declare -a array_a=()
declare -n array_b="array_a"
for ((i=0;i<=9;i++)); do
array_b+=($i)
done
length=${#array_a[*]}
for ((i=0;i<=$(($length-1));i++)); do
echo "${array_a[$i]}"
done
谢谢!