为什么命令 a-=2 失败?

为什么命令 a-=2 失败?

执行命令后declare -i a=5,命令a+=2成功,但命令a-=2失败。有人可以解释 bash 这种奇怪的行为吗?

答案1

Bash 在主 shell 语法中没有-=赋值运算符(算术上下文不同,见下文)。也就是说,虽然您可以使用=分配给变量,附加到非整数变量,或添加到整数变量,但+=没有 等与之配合。 Ksh 中的情况也是一样,它借用了 Bash 的语法(在这种情况下,就像在许多其他情况下一样); Zsh 也有类似的功能。-=*=

无论如何,其他组合赋值运算符+=对于非整数可能没有什么意义,并且由于常规“字符串”变量是最常见的变量,因此在主语法中使用这些运算符可能不值得。特别是因为var*=123它也是一个 glob,并且var/=123看起来像一条路径。但正如所说,+=对于非整数确实有效:

$ foo=123; foo+=456; echo $foo
123456

-=与往常一样,该手册对此有些简短,仅通过遗漏记录了缺失。部分3.4 外壳参数描述了变量赋值并提及了+=,但没有其他。

当然,在算术上下文中($(( .. ))(( .. ))),所有+=-=等均*=可用

$ foo=456; (( foo -= 123 )); echo $foo
333

答案2

在 Bash 中,算术评估是在 内部完成的(( )),例如((i=i+3))。从Bash 的手册页 ( man bash),

((表达))

表达式根据下面算术评估中描述的规则进行评估。

-=+=记录在算术评估部分中,以及= *= /= %= <<= >>= &= ^= |=和 都按您的预期工作 如果你使用算术符号。

+=没有该符号的工作是手册参数部分中描述的例外情况。

当 += 应用于已设置整数属性的变量时, value 将作为算术表达式进行计算,并添加到变量的当前值上,该值也会被计算。

总而言之,为了获得所需的行为,

#!/bin/bash
declare -i a=5
((a+=2))
echo $a
((a-=2))
echo $a

输出是7和5。

答案3

+=当与属性设置为整数类型的变量一起使用时,Bash 允许隐式算术计算declare -i。如果没有-i,它告诉 shell 执行“追加”而不是“添加”操作。除了在算术上下文中使用时之外, the-=或 other 运算符在任何地方都没有特殊含义。

请参阅 GNU bash 手册页的摘录

+=应用于已设置整数属性的变量时,值将被计算为算术表达式,并添加到变量的当前值上,该值也会被计算。

declare -i var=2
var+=2
printf '%d\n' "$var"
4

没有-i

declare foo=zoo
foo+=2
printf '%s\n' "$foo"
zoo2

现在对于其他运算符*=/=, %=, -=, <<=, >>=, &=, ^=,|=内部都支持$((..))

foo=144; (( foo /= 12 )); printf '%d\n' "$foo"
12

+=与数组一起使用时相关的另一个行为是将字符串arr+=foo附加foo到第一个索引处的元素,而arr+=(foo) 追加foo数组中下一个可用索引处的新元素。

答案4

其他答案备注为什么 a-=2不起作用(并且((a-=2)) 将要工作)。我认为值得记录一下,这a+=-2也将起作用:

$ declare -i a=5
$ echo $a
5
$ a+=2
$ echo $a
7
$ a+=-2
$ echo $a
5

相关内容