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

tmp*_*bin 6 bash arithmetic

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

ilk*_*chu 22

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

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

$ foo=123; foo+=456; echo $foo
123456
Run Code Online (Sandbox Code Playgroud)

与往常一样,手册对此有些简短,-=仅通过遗漏记录了缺失。第3.4Shell 参数描述了变量赋值并提到了+=,但没有其他内容。

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

$ foo=456; (( foo -= 123 )); echo $foo
333
Run Code Online (Sandbox Code Playgroud)

  • 是的,+= 被添加到 2000 年 ksh93j 中的 ksh93,2002 年 zsh-4.1.0-dev-4 中的 zsh,2005 年 3.1 中的 bash,2011 年 R40 中的 mksh。在 mksh 中,+=(在 `(( ...))`) 总是进行连接,即使变量被声明为整数。 (5认同)

Qua*_*odo 16

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

((表达))

表达式根据以下算术求值中描述的规则进行求值。

双方-=+=记录在算术评估部分,伴随着= *= /= %= <<= >>= &= ^= |=,正如你希望所有的工作 ,如果你使用的运算符号。

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

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

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

#!/bin/bash
declare -i a=5
((a+=2))
echo $a
((a-=2))
echo $a
Run Code Online (Sandbox Code Playgroud)

输出是 7 和 5。


Ini*_*ian 5

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

\n

请参阅 GNU bash 手册页的摘录

\n
\n

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

\n
\n
declare -i var=2\nvar+=2\nprintf '%d\\n' "$var"\n4\n
Run Code Online (Sandbox Code Playgroud)\n

没有-i

\n
declare foo=zoo\nfoo+=2\nprintf '%s\\n' "$foo"\nzoo2\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n
foo=144; (( foo /= 12 )); printf '%d\\n' "$foo"\n12\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n