Contents

Bash : LET语句与赋值

1. 概述

内置的let 命令是Bash和 Korn shell 基础软件的一部分。它的主要用途集中在使用基本算术运算构建变量赋值。

在本文中,我们描述了该命令的典型使用语法。因此,我们展示了将其与普通变量赋值 情况区分开来的所有有意义的属性。接下来,我们继续与执行类似变量分配和数学运算的替代命令进行比较。与每个检查的主题一起,为了提供对命令的扎实理解,我们通过适当的示例突出命令的引人注目的特征。

2. 语法和特征

let命令结合基本的数学计算执行变量赋值。它的典型语法以最简单的形式非常简单:

let statement1 [statement2 [...] ]

其中*statement1 [statement2 […]],*表示通过某种数学运算对数字或数值求值的变量赋值。

语句中涉及的变量获取命令的局部作用域,其属性值只能是定宽十进制整数。任何在变量上分配字符串的尝试都会导致失败。

最后,有一个重要的属性列表,概述了此命令的出色灵活性和有效性。与常见的变量赋值操作进行比较将有助于我们了解它的潜力。在以下部分中,我们将通过一些综合示例来探索基本属性。

2.1. 多语句和变量扩展

在单个命令中,多个语句可以轻松连接,而无需分号标点“;”。通常,它在标准赋值表达式中的存在区分了留在单行中的后续命令。我们可以在以下示例中轻松测试这一事实:

$ let age=25 weight=57

此外,关于参数扩展的一个增强特性是变量的扩展也可以通过名称简单地引用,而无需使用熟悉的前缀符号 ‘$’。让我们看看这在以下情况下如何应用:

$ let length=5 width=7 area=length*width
$ echo "length: $length - width: $width - area: $area"
length: 5 - width: 7 - area: 35

最后,前缀“$”的删除不是限制规则。这意味着前缀变量仍然可以单独存在或与前一种类型混合存在。在这种情况下,变量扩展前缀的存在不会发生冲突:

$ let "x=3" "y=4" "z2=x**2+$y**2"; echo $x, $y, $z2
3, 4, 25

2.2. 使用双引号的赋值中的变量和操作

当赋值定义用双引号括起来时, let命令的其他有趣功能就会出现。

在正常的变量赋值实例下,不能存在空格。对于赋值运算符 ‘=’ 和任何二元运算符,都必须保持一个结构与语法上附加的运算符和操作数。而对于典型的变量声明,任何中间的空格都会破坏赋值:

$ year= 1981
bash: 1981: command not found...
$ volume =125
bash: volume: command not found...

let命令在表达式周围加上双引号后成功。在这种情况下:

$ let "year= 1981" "volume =5**3" 
$ echo "year: $year - volume: $volume" 
year: 1981 - volume: 125

作为替代解决方案,多个表达式可以在单个双引号实体处合并,随后的语句用逗号分隔 ‘,’。后一个例子将出现在这个规定下,如下所示:

$ let "year= 1981 , volume =5**3"

2.3. 范围可见性

让我们看看let命令的正确环境 什么特点。**该命令为在其中起作用的变量构建了一个本地范围。**与变量的任何其他局部字符类似,此环境中预定义变量的存在会导致覆盖:

$ version=10 let "version=11, release = version"; echo "$version, $release"
11, 11

此外,当变量设置在其本地范围内时,会出现一个有趣的属性,但尚未计算其有效值。在这种情况下,当我们评估变量时,值不会更新。让我们在以下示例中查看此案例的详细信息:

$ let "count=11, max=count++"; echo $count,$max
12,11

上面,在max赋值时count变量的增量仍然是未决的。因此,正确的值仍然保持不变。通过在分配max之前要求对count update 进行评估,更新适用于当前 shell。最后,这也适用于max变量:

$ let "count=11, max=++count"; echo $count,$max
12,12

2.4. 使用let命令退出状态

** let命令结束时的退出状态由分配给最右边变量的值决定。**

独立于任何先前语句的分配值,最后一个表达式是定义返回的退出状态的表达式。更明确地说,在最后一条语句中,如果变量的值对应于 0,则返回的退出状态为 1(FALSE)。在任何其他情况下,分配正值或负值时,返回的退出状态为 0 (TRUE)。

下面,我们可以通过一个简单的示例观察退出状态在每种情况下的作用。退出状态评估的检索是通过变量*$?* :

$ let "b=-1, k=0"; echo $?
1
$ let "b=0, k=0"; echo $?
1
$ let "b=0, k=1"; echo $?
0

2.5. 数学运算

let命令构造中的赋值语句中允许进行大量数学运算。下面,我们列出了具有优先重要性递减顺序的运算符。位于同一行的运算符授予相同级别的优先级。

数学运算符的优先顺序由以下列表确定(最高优先级在顶部,最低优先级在底部):

  • 后递增、后递减 ( id++ , id– )
  • 预增、预减(++id–id
  • 一元减号,一元加号(-+
  • 逻辑否定,按位否定 ( ! , ~ )
  • 求幂 ( ** )
  • 乘法,除法,余数(模)(*/%
  • 加法,减法(+-
  • 按位移位 ( « , » )
  • 数值比较 ( < , > , <= , >= )
  • 平等,不平等(==!=
  • AND(按位*&*)
  • 异或(按位*^*)
  • 或(按位 |
  • 逻辑与 ( && )
  • 逻辑或 ( || )
  • 三元运算符 ( * ? : * )
  • 分配(=*=/=%=+=-=«=»=&=^=|=
  • 表达式列表运算符(* *)

具有多个运算符的表达式,用括号将这些适当的聚合可以改变默认的执行优先顺序。通过括号内的语句,算子的求值可以按照合理选择的结构以高级顺序执行。这样,重新排序的类型可能会覆盖上面列表中描述的标准操作的评估优先级。

总之,通过深入了解数字表示,以 0 开头的数字表达式本机表示八进制数。此外,前导 0x 或 0X 字符表示十六进制数。使用前缀 base# ,数字可以类似地应用于 2-64 范围内的不同算术基数*。*每当此前缀不存在时,我们默认使用标准基数 10。

3. let命令的替代选项

let命令提供与变量赋值和数学运算相关的特定特性和增强功能。然而,这并不意味着标准的变量分配方法不适用于类似的任务。

关于算术运算的求值,算术求值(( ))和算术扩展$(( ))构造执行等效的工作。它们的区别主要在于直接或间接的赋值。我们用下一个简单的例子来说明这个事实:

$ a=3; n=50; ((x=a+n)) ; echo $a, $n, $x
3, 50, 53
$ a=3; n=50; x=$((a+n)) ; echo $a, $n, $x
3, 50, 53

通常,我们不能在赋值和二元运算符周围使用空格。但是使用let命令,我们通过打开整数属性获得了这种便利的优势。在以下示例中,我们可以了解其实际工作原理。例如,使用余数运算符“%”和逻辑位移运算符“«”:

$ declare -i customVar1; customVar1="9 % 5"; echo $customVar1
4
$ x=2; declare -i customVar2; customVar2="8 << x"; echo $customVar2
32

在这种特殊情况下,变量customVar1customVar2通过内置命令declare 采用整数值。此命令产生以let命令风格执行算术运算的能力。

或者,能够评估算术表达式的类似命令是命令expr 。尽管如此,这仍然可以相当地执行算术运算,但代价是稍微特殊的语法规则。让我们在下面检查这些特定属性。

首先,算术运算符必须被空格包围:

$ expr 2 + 9
11

此外,特定的运算符(例如乘法 (*) 和除法 (/) 运算符)必须以转义字符“\”作为前缀。例如:

$ expr 3 \* 22
66
$ expr 15 \/ 4
3

此外,数字比较运算符需要与双引号一起使用:

$ x=5; y=18 ; expr  $x ">" $y
0

最后,具有变量扩展的操作以通常的模式发生:

$ x=5; y=18 ; expr  $x + $y
23

4. 与标准赋值案例的主要区别

let命令结构已经实现了各种不同的特性,这些特性将它与常见的赋值操作区分开来。下面,我们重点介绍这两种情况之间最显着的区别:

  • 不使用评估参数扩展前缀符号’$‘的变量引用
  • 在单个语句中使用多个赋值(双引号语法类型)
  • 空值的计算结果为 0
  • 可以在赋值运算符 ‘=’ 或任何二元运算符周围任意使用空格(双引号语法类型)
  • 本地范围环境
  • 具体退出代码返回值取决于最右边的赋值
  • 可以执行算术运算,例如求幂、余数计算(模)和逻辑运算(OR、AND、XOR、位移和数字反转)