这个脚本有什么问题?我试图定义 A1=1, B1=1, C1=1
LIST="A B C"
for x in $LIST
do
"$x"1=1
done
结果是:
./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found
答案1
变量赋值的形式是变量名、等号、(可选)值。
这是一个有效的分配:
ABC=123
"$x"1=1
不是有效的赋值,因为"$x"1
不是变量名。可能是评估类似于变量名,但事实并非如此。事实上,shell 认为它是一个命令。
实现您想要实现的目标的一种方法是:
eval "$x"1=1
bash 中的另一种方法(但不是其他 shell 中)是:
declare "$x"1=1
或者也(同样仅限 bash):
let "$x"1=1
(你的情况没有太大区别。)
但是,作为贾库杰中指出的评论,如果您的 shell 有数组(ksh、bash 或 zsh),您可能想要使用数组。
为了完整性:
eval
执行任意命令。因此,如果等号右侧有一个扩展为某个命令的变量,则该命令将被执行。下面的代码:x=a y='$(echo hello)' eval "$x=$y"
相当于
a=hello
.declare
是一个 bash 内置命令,用于分配变量,并且不会执行任何命令。下面的代码:x=a y='$(echo hello)' declare "$x=$y"
相当于
a='$(echo hello)'
.let
与 , 类似declare
,因为它不执行命令。但与 相反declare
,let
可以用于算术运算:let a="1 + 2"
相当于
a=3
.
答案2
bash 常见问题解答有一个条目关于间接。在大多数用例中,您实际上应该做的是使用关联数组或索引数组。您还可以使用
func_call_by_reference() { # Bash 4.3
typeset -n ref=$1 # nameref to the variable named by the caller
ref=( "val1" "val2" ... ) # return an array by reference
}
请参阅常见问题解答条目,了解执行此操作的更多选项,同时仍避免混乱的eval
引用。
答案3
您可以使用如下代码。在您的代码中,shell"$x"1=1
作为命令执行,因为它不是有效的变量分配。
LIST="A B C"
for x in $LIST
do
a=$(echo "$x"1)
let $a=1
done