let,expr和$ 之间的区别
我想知道究竟是什么区别
a=$[1+1] a=$((1+1)) let a=1+1 a=$(expr 1 + 1 )
所有4分配变量a和2,但有什么区别?
从我到目前为止发现的是,expr是慢的,因为它不是一个真正的shell内置。 但不仅如此。
所有这些都涉及算术,但以不同的方式处理,变量通过不同的方式创建。 其中一些特定于bash
shell,而另一些则不是。
-
((...))
被称为算术扩展,这是典型的bash
和ksh
shell。 这允许进行简单的整数运算,但没有浮点数。((...))
只是一个动作,所以$((..))
代替了操作的输出。 -
$[...]
是不推荐使用的算术扩展的旧语法。 另见 。 这可能会保留,以便旧的bash
脚本不会中断。 这在ksh93
中ksh93
,所以我的猜测是这种语法是特定于bash的。 注意 :空格在这里非常重要; 不要将$[1+1]
与[ $a -eq $b ]
类的东西混淆。[
使用空格称为test
命令,您通常在决策部分中看到它。 它的行为和目的非常不同。 -
let
是一个bash
和ksh
关键字,允许通过简单的算术评估进行变量创建。 如果您尝试分配一个字符串,例如let a="hello world"
您将收到语法错误。 适用于bash
和ksh93
。 -
$(...)
是命令替换,您可以从中获取命令的输出并分配给变量。 你的命令是expr
,它接受位置参数,比如expr arg1 arg2 arg3
,所以空格很重要。 它有点像整数算术的小命令行计算器,加上一些真/假和正则表达式的东西。 这是一个与shell无关的命令。
值得注意的是,算术扩展和命令替换是由POSIX标准指定的,而let
和$[...]
则不是。
-
let
命令执行算术评估 ,是内置的shell。-
运行此命令,您什么也得不到(仅评估):
let 1+2
-
-
$(( ))
用于执行算术扩展 : 在此处阅读-
运行这个,你会得到一个错误(因为扩展):
$((1+2))
-
-
$[ ]
是算术扩展的旧语法:旧格式$ [expression]已弃用,将在即将发布的bash中删除。 Bash Man Page
-
expr
是一个二进制命令,如果你想在命令子项中进行算术扩展,你可以使用它:echo $(expr 1 + 2) echo `expr 1 + 2`
由于上面的一些答案特别提到ksh93
,值得注意的是它可以做浮点数学,例如:
$ print $((1.0/3)) 0.333333333333333333
您可以使用printf控制输出的精度,例如:
$ printf "%.4f\n" $((1.0/3)) 0.3333
必须至少将一个参数指定为上面的浮点数。 如果两者都指定为整数,那么只进行整数数学运算,例如:
$ print $((1/3)) 0
当您需要在shell脚本中进行浮点数学运算时,这可能会有所帮助,因为您可以避免调用外部命令。
let
在cron中不起作用。 我认为这是因为let
拥有自己的环境。 使用$((...))
因为它是POSIX。 例如,
let x=1+2 echo x=$x
在cron中,从shell运行时产生“x =”,但“x = 3”。
x=$((1+2)) echo x=$x
在所有情况下都得到“x = 3”。