【发布时间】:2020-08-27 10:37:42
【问题描述】:
StackOverflow bash 上的一个常见比喻是:“为什么 x=99; echo {1..$x} 不起作用?”
答案是“因为大括号在参数/变量之前展开”。
因此,我认为应该可以使用单个 $ 和大括号来扩展多个变量。我希望a=1; b=2; c=3; echo ${{a..c}} 打印1 2 3。首先,内大括号将扩展为${a} ${b} ${c}(在编写echo \${{a..c}} 时会这样做)。然后该结果将进行参数扩展。
但是,我得到了-bash: ${{a..c}}: bad substitution,所以{a..c} 根本没有展开。
Bash's manual 更具体一点(强调我的)。
在分割成标记后在命令行上执行扩展 [...] 展开顺序为:大括号展开;波浪号扩展、参数和变量扩展、算术扩展和命令替换(以从左到右的方式完成);分词;和文件名扩展。
注意该列表中的; 和,。 “从左到右的时尚”似乎适用于; 之前的整个(因此无序)列表。就像数学运算符 * 和 / 没有优先级一样。
好的,所以大括号扩展实际上并不比参数扩展具有更高的优先级。只是{1..$x}和${{a..c}}都是从左到右求值的,也就是说大括号{在参数$x之前,参数${在大括号{a..c}之前。
至少我是这么认为的。但是,当使用$ 而不是${ 时,左侧的参数会在右侧的大括号之后展开:
# in bash 5.0.3(1)
x=nil; x1=one; x2=two
echo ${x{1..2}} # prints `-bash: ${x{1..2}}: bad substitution`
echo $x{1..2} # prints `one two`
问题
- 可能是 bash 手册有缺陷还是我看错了?
- 如果手册有缺陷:所有扩展的确切顺序是什么?
我只是问,因为我很好奇。我不打算在任何地方使用像$x{1..2} 这样的想法。我对解决多个变量的更好的解决方案或替代不感兴趣(例如数组切片${array[@]:1:2})。我只是想更深入地了解。
【问题讨论】:
-
我认为错误替换错误的发生是因为
x{1..2}不允许根据valid_brace_expansion_word。见subst.c:8781。
标签: bash bash command-precedence