了解 bash 参数扩展的操作顺序

了解 bash 参数扩展的操作顺序

我从 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 的文件。

相关内容