POSIX的解释:
先感受下面的几行命令:
[root@localhost shell]# set -- one two three # 设置 $1 $2 $3
[root@localhost shell]# echo $1
one
[root@localhost shell]# n=1
[root@localhost shell]# echo ${$n} ## 第一次尝试用大括号
bash: ${$n}: bad substitution
[root@localhost shell]# echo $($n) ## 第二次尝试用小括号
bash: 1: command not found
[root@localhost shell]# echo ${!n} ## 第三次尝试用!解析
one
[root@localhost shell]# eval echo \${$n}
one
[root@localhost shell]#
可以看出,最后两次的n被当成变量解析了。
${$n}
是语法错误。在大括号中只能出现带前缀或后缀的变量名。这时可以用下面的方式:
echo ${!n}
$(...)
这个命令将小括号内的命令在新的进程中执行,即继承了当前shell变量和设置的子shell,并接收它的输出。所以$($n)
把$n
当作一个shell命令。
eval echo \${$n}
把参数传给 eval
。
下面讲一个小程序:
#!/bin/bash
count=$# # 参数个数
cmd=echo
while [ $count -gt 0 ]
do
cmd="$cmd \$$count" # cmd后接 $count
count=`expr $count - 1` # $count减1
done
eval $cmd # 解析 $cmd 并执行
执行结果:
[root@localhost shell]# bash eval.sh hello world to bash shell
shell bash to world hello
参考文章:
What is the “eval” command in bash?
eval command in Bash and its typical uses