执行命令后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