作业:表达式还是命令?

作业:表达式还是命令?

在 Bash 和 Posix shell 中,有多种形式的命令,如果我没猜错的话,赋值就是一种命令形式(特别是简单命令)。

但是let可以用在赋值前面,并且let应该用在表达式前面。所以如果我是对的的话,赋值也是一个表达式。

let前面有和没有的赋值都用作命令,两者之间有什么区别?我主要问的是它们的用途之间的差异,即何时使用哪个。例如

$ aaa=1

$ let aaa=1

答案1

let <EXPRESSION>虽然本身不​​符合 POSIX 标准,但可以用符合 POSIX 的方式表示为

[ "$(( <EXPRESSION> ))" -ne 0 ]

与普通赋值相反,let它还计算赋值(表达式)并根据结果返回退出代码:

$ aaa=1; echo $?
0
$ aaa=0; echo $?
0

$ let aaa=1; echo $?
0
$ let aaa=0; echo $?
1

答案2

据我所知,let不是POSIX 兼容外壳检查同意:

$ cat test.sh
#!/bin/sh
let a=3

$ shellcheck test.sh
In test.sh line 2:
let a=3
^-- SC2039: In POSIX sh, 'let' is undefined.

bash 手册页说:

((expression))

表达式根据下面算术评估中描述的规则进行评估。如果表达式的值非零,则返回状态为0;否则返回状态为1。这与let“表达式”完全相同。

算术评估

shell 允许在某些情况下计算算术表达式(请参阅 let 和声明内置命令以及算术扩展)。尽管除以 0 会被捕获并标记为错误,但评估是在固定宽度整数中完成的,不会检查溢出。运算符及其优先级、结合性和值与 C 语言中的相同。以下运算符列表按同等优先级运算符分组。级别按优先级递减的顺序列出。

……

= *= /= %= += -= <<= >>= &= ^= |= 任务

let arg [arg ...] 每个 arg 都是要评估的算术表达式(请参阅上面的算术评估)。如果最后一个参数的值为 0,则 let 返回 1;否则返回 0。

因此,在 bash 中,赋值也是一个表达式,并且由于您可以使用 评估一个或多个表达式let,因此您可以使用单个 执行一个或多个赋值let。但是,如上所述,它不符合 POSIX 标准。

答案3

这记录在 的文档中let,就在下面,它说它需要一个表达式。

让表达式[表达式...]

let 内置命令允许对 shell 变量执行算术运算。每个表达式根据下面给出的规则进行计算壳算术如果最后一个表达式的计算结果为 0,则 let 返回 1;否则返回 0。

壳算术包括赋值运算符=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, 和|=。一般来说,这与普通赋值语句无关,普通赋值语句不应用任何附加处理。

答案4

变量赋值既不是表达式也不是命令,它们是“简单命令”语法的一部分。赋值可以出现在命令字之前并修改该命令的环境。如果分配出现时没有命令,它们会修改当前 shell 的环境。

看:https://www.gnu.org/software/bash/manual/html_node/Simple-Command-Expansion.html

另请参阅这个答案: 这个 shell/Bash 语法是什么:someVariable=someValue someCommand

let是一个 Bash 内置命令,它实现了自己的语法和赋值运算符,正如@Michael Homer 指出的那样。 help let提供方便的参考。

相关内容