我从 bash 编程书中读到了一个类似的例子:
$ cat indirection
#!/usr/bin/env bash
set -x
num=1
eval "${!num#*:}"
$
当我用 执行脚本时bash indirection "test:echo blah"
,脚本的最后一行是如何处理的?我想首先会发生间接,这样就eval "${!num#*:}"
变成了eval "${1#*:}"
?然后子字符串被删除并eval "${1#*:}"
变成eval echo blah
?如果是,那么为什么eval
需要,即${!num#*:}
代替eval "${!num#*:}"
会提供相同的结果?
答案1
参数展开的输出为:
$ echo "${1#*:}"
echo blah
嗯,是的,在这个具体案例中:
$ set -- "test:echo blah"
$ eval "${1#*:}"
blah
$ ${1#*:}
blah
执行相同的命令。但这并不总是正确的:
$ "${1#*:}"
bash: echo blah: command not found
事实上,包含 shell 元字符的字符串即使不加引号也无法正常工作。
$ set -- "test:echo blah > file"
${1#*:}
blah > file
重定向没有发生,但是(注意将创建一个文件):
$ eval "${1#*:}"
将在 PWD 中创建一个名为 file 的文件。