回应我的评论这个问题关于 SF,OP 声称
for i in {1..$NUM}
在 bash 中正确扩展。我可以访问 bash 4.0.33 (Ubuntu)、3.2.25 (Centos) 和 3.00.16(1) (solaris 10)。这些都不会扩展 {1..$NUM}。
有谁知道哪些版本的 bash 进行了扩展?如果不是 bash 那是什么?我知道 zsh 会进行扩展,但在 OP 的脚本中,shebang 应该消除别名的可能性?
答案1
我很确定提出有关服务器故障问题的人是错误的。他们要么故意遗漏了一些细节,要么不知道机器上的一些奇怪的配置(/bin/bash 作为其他内容的链接)。我尝试了两周前的 bash 4.2 版本、CentOS 5 的 bash 3.2 以及我自己刚刚构建的 bash 2.05a(2001 年起)。
最古老的来源ftp.gnu.org是 1.14,但这并不能干净地构建,而且我不确定尝试它是否值得。该版本的文档包含与现代文档完全相同的关键短语:
The order of expansions is: brace expansion, tilde expan- sion, parameter, variable, command, and arithmetic substitu- tion (done in a left-to-right fashion), word splitting, and pathname expansion.
但实际上,现在我想起来了,这是毫无意义的,因为“{x..y}”语法是bash 3.0 中添加,使得之前的查找毫无用处。
那么,让我尝试一下 3.0...对吧。同样的行为。
嗯是的。我非常怀疑。有些东西没有加起来。
(之后...)
啊哈!服务器故障提问者承认”对不起。我的错。我已将实际数字放入 {1..10} 中的 i 中,因此效果很好。“那么,就这样吧。
答案是这问题是“没有哪个版本的 bash 可以这样工作”。 :)
答案2
要扩展它,你必须使用eval
:
$ echo {1..5}
1 2 3 4 5
$ NUM=5
$ echo {1..$NUM}
{1..5}
$ eval "echo {1..$NUM}"
1 2 3 4 5
不过要非常非常小心eval
!如果您接受用户输入,请确保在执行此类操作之前检查它是否确实是一个数字。正如我的同事所说:“eval
是邪恶的!”
答案3
大括号扩展不会扩展变量,因为大括号扩展是 shell 扩展的第一步,变量是稍后扩展的。
从 bash 手册页:
大括号扩展在任何其他扩展之前执行,并且其他扩展特有的任何字符都将保留在结果中。它是严格的文本。 Bash 不会对扩展上下文或大括号之间的文本应用任何语法解释。
所以:
NUM=4
for i in {1..$NUM}
do
echo $i
done
印刷
{1..4}