当前位置: 首页>>技术教程>>正文


let、expr 和 $[] 之间的区别

, ,

问题描述

我想知道

a=$[1+1]
a=$((1+1))
let a=1+1
a=$(expr 1 + 1 )

所有 4 个都将 2 赋值给变量 a,但是有什么区别呢?

从我目前发现的情况来看,expr 速度较慢是因为它不是真正的 shell 内置命令。但仅此而已。

最佳办法

所有这些都处理算术,但方式不同,变量的创建方式也不同。其中一些是 bash shell 特有的,而另一些则不是。

  • $((...)) 被称为 arithmetic expansion ,这是 bashksh shell 的典型特征。这允许进行简单的整数运算,但不能进行浮点运算。表达式的结果将替换表达式,例如 echo $((1+1)) 将变成 echo 2

  • ((...)) 被称为 arithmetic evaluation,可用作 if ((...)); thenwhile ((...)) ; do 语句的一部分。算术扩展 $((..)) 替换操作的输出,可用于分配变量(如 i=$((i+1)) 中所示),但不能用于条件语句。

  • $[...] 是旧的算术扩展语法,已被弃用。See also。保留它可能是为了让旧的 bash 脚本不被破坏。这在 ksh93 中不起作用,所以我猜这个语法是 bash-specific。注意:空格在这里非常重要;不要将 $[1+1][ $a -eq $b ] 之类的东西混淆。带有空格的 [ 称为 test 命令,您通常会在 decision-making 部分中看到它。它在行为和目的上非常不同。

  • letbashksh 关键字,允许使用简单的算术评估创建变量。如果您尝试在那里分配字符串(如 let a="hello world"),您将收到语法错误。适用于 bashksh93

  • $(...) 是命令替换,您实际上是将命令的输出赋值给变量。此处的命令是 expr ,它接受位置参数,如 expr arg1 arg2 arg3 ,因此空格很重要。它有点像一个小型的 命令行 计算器,用于整数运算,加上一些真/假和正则表达式类型的东西。这是一个 shell-neutral 命令。

还值得注意的是,算术扩展和命令替换由 POSIX standard 指定,而 let$[...] 则没有。

次佳办法

  • let 命令执行算术评估,并且是 shell 内置。\n

    • 运行此命令,您将不会得到任何结果(仅计算结果):

      \\n

      let 1+2\\n
  • $(( )) 用于执行算术扩展:read here \n

    • 运行这个,你会得到一个错误(由于扩展):

      \\n

      $((1+2))\\n
  • $[ ] 是算术扩展的旧语法:\n\n旧格式 $[expression] 已弃用,将在即将推出的 bash 中删除。\n Bash 手册页\n

  • expr 是一个二进制命令,如果您想在命令替换中进行算术扩展,可以使用它:

    \n

    echo $(expr 1 + 2) \necho `expr 1 + 2`\n

第三种办法

由于上面的一些答案特别提到了 ksh93,因此值得注意的是它可以进行浮点数学运算,例如:

$ print $((1.0/3)) 
0.333333333333333333

您可以使用 printf 控制输出的精度,例如:

$ printf "%.4f\n" $((1.0/3))
0.3333

至少一个参数必须指定为浮点数,如上所述。如果两者都指定为整数,则只进行整数运算,例如:

$ print $((1/3))  
0

当您需要 shell 脚本中的浮点数学时这会很有用,因为您可以避免调用外部命令。

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/14585.html,未经允许,请勿转载。