使用eval进行动态数组启动时出现语法错误

时间:2017-05-20 08:29:49

标签: arrays bash

var=(a b c)
eval "${var[0]}=(1 2)"

然后我收到一条错误消息

bash: syntax error near unexpected token `1'

那么语法错误意味着什么以及如何解决它?非常感谢!

1 个答案:

答案 0 :(得分:2)

了解eval如何影响您所撰写的行的最简单方法是将eval替换为echo。使用echo发出命令,显示:

$ var=(a b c)
$ echo "${var[0]}=(1 2)"
a=(1 2)

如您所见,eval行将执行的命令将设置变量$a而不是变量$var。事实上,如果出于任何原因,${var[0]}的值变为1(正如您尝试的那样),eval行将变为:

$ var=(1 2)
$ echo "${var[0]}=(1 2)"
1=(1 2)

如果获得eval ed,则会触发您看到的错误。

解决方案取决于您愿意完成的工作。

如果要更改存储在$a内的变量${var[0]}的值,那么您可以使用:

declare -a "${var[0]}=(1 2)"

如果${var[0]}1,则会发出此错误:

 bash: declare: `1=(1 2)': not a valid identifier

IMO是一个更有意义的消息。

或者,如果你真的想避免使用eval:

#! /bin/bash
var=(a b c)
values=(1 2)
read -ra "${var[0]}" <<< "${values[@]}"
declare -p "${var[0]}"

将打印:

declare -a a=([0]="1" [1]="2")

如果$values可能包含空格或换行符(或修改后的IFS可能包含的值),则需要更复杂的脚本:

#! /bin/bash
var=(a b c)
values=("1 2" "3 4")
i=0
while IFS='' read -rd $'\0';do
    declare "${var[0]}[$i]"="$REPLY" ;
    ((i++));
done < <( printf '%s\0' "${values[@]}")

declare -p "${var[0]}"

或者,对于更新的bash版本(自bash-4.4起),您可以使用readarray的-t选项(删除分隔符):

#! /bin/bash
var=(a b c)
values=("1 2" "3 4")

IFS='' readarray -td $'\0' "${var[0]}" < <(printf '%s\0' "${values[@]}")

declare -p "${var[0]}"