哪里在bash递归变量扩展/壳数字背景从何而来? [英] Where does the recursive variable expansion in bash/shell numeric contexts come from?

查看:191
本文介绍了哪里在bash递归变量扩展/壳数字背景从何而来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用方面的POSIX规范各国算术展开

The POSIX spec states with regard to Arithmetic Expansion that

[我] F中的shell变量x包含形成一个有效的整型常量,可选择其中一个领先的加号或减号,那么算术扩展的值$((X))和$(($ X) )应返回相同的值。

[i]f the shell variable x contains a value that forms a valid integer constant, optionally including a leading plus or minus sign, then the arithmetic expansions "$((x))" and "$(($x))" shall return the same value.

这是一个合理的快捷方式,相当不错清理复杂的前pressions。

Which is a reasonable shortcut and cleans up complicated expressions rather nicely.

庆典(版本 3.2.25(1)-release 从CentOS的5和 33年3月4日(1)-release 与debian不稳定),以及KSH(版本AJM93吨+ 2010-06-21 从CentOS的5)似乎都向前迈进一步那么这不过。

bash (versions 3.2.25(1)-release from CentOS 5 and 4.3.33(1)-release from debian unstable) as well as ksh (Version AJM 93t+ 2010-06-21 from CentOS 5) all seem to go one step farther then that however.

他们似乎都递归扩展算术扩展中遇到的变量(和数字环境中的 [使用该数值运算的结果)。

They all seem to recursively expand variables encountered in arithmetic expansion (and numeric contexts in [[ resulting from using the numeric operators).

具体做法是:

$ set -x
$ bar=5
+ bar=5
$ foo=bar
+ foo=bar
$ [ foo -gt 4 ]; echo $?
+ '[' foo -gt 4 ']'
-bash: [: foo: integer expression expected
+ echo 2
2
$ [[ foo -gt 4 ]]; echo $?
+ [[ foo -gt 4 ]]
+ echo 0
0
$ [[ foo -eq 0 ]]; echo $?
+ [[ foo -eq 0 ]]
+ echo 1
1
$ [[ foo -eq 5 ]]; echo $?
+ [[ foo -eq 5 ]]
+ echo 0
0
$ (( foo == bar )); echo $?
+ ((  foo == bar  ))
+ echo 0
0
$ (( foo == 1 )); echo $?
+ ((  foo == 1  ))
+ echo 1
1

来自哪儿呢这种行为,为什么它会永远是可取的?

Where does this behavior come from and why would it ever be desirable?

这使得使用 [ [明确 安全使用时少与数字运算符,因为无效的价值观和印刷错误被脚本错误被默默地有效(但可能错误)的测试去了。

It makes using [[ in place of [ explicitly less safe when used with numeric operators because invalid values and typographical errors go from being script errors to being silently valid (but likely erroneous) tests.

编辑:作为一个方面的问题,如果有人碰巧知道的的这一特性被加入到庆典的/ etc。我有兴趣知道这一点。

As a side question if anyone happens to know when this "feature" was added to bash/etc. I would be interested in knowing that as well.

推荐答案

这是比你想象的更糟糕。该变量的值被递归地视为一个算术前pression:

It's worse than you think. The value of the variable is recursively treated as an arithmetic expression:

$ foo='bar+bar'
$ echo $((foo))
10

壳牌算术bash的手册中说

的变量的值作为运算前pression评价时,它被引用时,或者当已在实施利用声明-i'的整数属性的变量被分配一个值。

The value of a variable is evaluated as an arithmetic expression when it is referenced, or when a variable which has been given the integer attribute using ‘declare -i’ is assigned a value.

后半部分意味着你可以这样做:

The latter part means you can do:

$ declare -i int
$ int=bar+bar
$ echo $int
10

请注意,这一切都不是违反你上面引述的规范。它只是说,如果变量的值是一个整型常量应该做什么。这并不是说,如果该值是另一回事,这让那个打开的实现添加这样的扩展应该怎样做。 击黑客维基解释它:

如果该变量不成立,看起来像一个有效的前pression(数字或操作)的值,前pression被重新用来参考,例如命名参数

If the variable doesn't hold a value that looks like a valid expression (numbers or operations), the expression is re-used to reference, for example, the named parameters

如果最终的扩张不是有效的前pression,你会得到一个错误:

If the eventual expansion is not a valid expression, you'll get an error:

$ foo='a b'
$ bar=foo
echo $((bar))
bash: a b: syntax error in expression (error token is "b")

所以,如果您的变量包含随机的东西,它可能会导致错误。但如果只包含一个字,这是有效的变量语法,如果变量没有设置,将评估为 0

这篇关于哪里在bash递归变量扩展/壳数字背景从何而来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆