为什么bash大括号扩展在某些算术表达式中有效,而在其他表达式中无效?
我正在编写一个非常简单的bash脚本,我有一个问题,那就是为什么不推荐的$[]可以完美地工作,而$(())似乎破坏了整个过程 我指的代码是:为什么bash大括号扩展在某些算术表达式中有效,而在其他表达式中无效?,bash,brace-expansion,Bash,Brace Expansion,我正在编写一个非常简单的bash脚本,我有一个问题,那就是为什么不推荐的$[]可以完美地工作,而$(())似乎破坏了整个过程 我指的代码是: for i in {1..10}; do printf %4d $[{1..10}*i] echo done 在这个版本中,我没有问题,但我不想使用不推荐的bash元素,这就是为什么我想切换到$(()) 不幸的是,一旦我将代码更改为: printf %4d $(({1..10}*i)) 我收到一个错误: ./script_bash.s
for i in {1..10};
do
printf %4d $[{1..10}*i]
echo
done
在这个版本中,我没有问题,但我不想使用不推荐的bash元素,这就是为什么我想切换到$(())
不幸的是,一旦我将代码更改为:
printf %4d $(({1..10}*i))
我收到一个错误:
./script_bash.sh: line 8: {1..10}*i: syntax error: argument expected (error token is "{1..10}*i")
我非常感谢您在这方面的帮助。$(())
用于算术表达式,而大括号扩展不是在算术中完成的
使用循环创建一个数组:
for i in {1..10}
do
vals=()
for j in {1..10}
do
vals+=($((i*j)))
done
printf "%4d" ${vals[@]}
done
为1990年的回归设定了一条道路 Bash根据POSIX P1003.2d9(大约1990年)实现了
$[]
语法,这是已发布的P1003.2-1992的草案。在草稿和标准之间的两年时间里,POSIX取而代之的是ksh88$(())
语法和行为。Chet Ramey(bash维护人员)说:
猛击。。。实现了$[…],因为没有其他
语法,并获得一些操作经验
外壳中的算术展开。Bash-1.14。。。列出两种形式的算术展开,但按
1995年发布bash-2.0时,手册只提到
美元(…)表格
这向我表明,$[]
形式是实验性的,当POSIX采用$(())
语法时,它具有某些行为(如大括号扩展)被指定为遗忘。这些实验行为被保留了下来,因为在野外已经有脚本依赖于它们(请记住,2年多过去了)
Chet在同一个线程中明确指出,$[]
表单已过时,但未弃用:
现在,继续拖动$[…]语法几乎没有什么问题。
它只需要几十个字节的代码。我不打算把它移走
其中提到了语法(我的重点):
在早期的提案中,使用了$[表达式]形式它在功能上等同于当前文本的“$(())”,但有人反对1988年的KornShell已经实现了“$(())”,并且没有令人信服的理由发明另一种语法。此外,“$[]”语法有一点不兼容,涉及case语句中的模式
因此,bash中实现的行为并不完全符合规范,但由于没有删除它的计划,如果它能巧妙地解决您的问题,我认为没有理由放弃它的好处。然而,正如@Barmar的评论所指出的,最好对代码进行注释并将其链接到此处,以便未来的开发人员了解您的意思 printf%4d$({1..10}*i))
由于参数在bash
中的展开顺序,因此无法工作。大括号扩展({}
)比算术扩展($(())
)早于bash
完成。如果换个角度看,你的代码肯定能工作
从manbash
:
展开顺序为:支撑展开;波浪线展开、参数和变量展开、算术展开和命令替换(以从左到右的方式完成);分词;和路径名扩展
遇到这样的狂欢。这个问题要求解释,而不是解决,但这里有一个$(())的表达方式
for i in {1..10}; do
printf %4d $(eval echo '$(('{1..10}'*i))')
echo
done
大括号展开在算术展开中被禁止,就像参数展开一样
(bash手册)
为避免与参数扩展冲突,不使用字符串“${”
被认为有资格扩展支撑,并禁止扩展支撑
直到结束“}”
$(())
是一个算术表达式。它不进行常规的通配符或大括号扩展。但是,另一方面,为什么大括号扩展在$[]
中进行?这是我第一次听说$[]
。我在bash手册中找不到它。它是一个不推荐使用的伪等价物,相当于$(
,请看,我猜从技术上讲,您的第一句话是不正确的,因为表面上$[]
也是“算术表达式”的意思但我猜想,在他们创建它的时候,他们并没有认为算术扩展与它自己的语法完全不同的上下文。虽然它没有明确地被弃用(实际上有一个被弃用的特征列表吗?),事实上,手册中甚至没有提到它,这是避免它的一个强有力的指示。即使它从未真正消失,其他程序员也不会理解它。我已经编写了30年的shell脚本,我以前从未看到过这一点,我相信我并不孤单。与您链接的bash hackers页面上的其他功能相比到目前为止,它们仍然在手册中。@Barmar当前的POSIX规范中提到了它,一些发行版修补了bash手册页来提及它。尽管如此,我已经详细阐述了我的用法“建议”。