这些bash语句都是等价的吗?

时间:2011-05-13 15:54:10

标签: bash

我刚发现这个很棒的网站。当我想到以下问题时,我正在阅读bash标记的帖子:

此代码:

var=$RANDOM

var1=$[ $var % 13 ]
echo "var1 = $var1"

var2=$( $var % 13 )
echo "var2 = $var2"

var3=$(( $var % 13 ))
echo "var3 = $var3"

var4=`expr $var % 13` # Note revised from original post by adding the expr
echo "var4 = $var4"

生成此输出:

var1 = 7
./question: line 7: 23225: command not found
var2 = 
var3 = 7
var4 = 7

因此只有var2语句不起作用。我的问题是:是否应该考虑使用其他三个中的哪一个或者是否应该考虑其他因素来个人选择?

(我在看到回复后广泛地编辑了这个问题。希望我这样做是正确的。)

4 个答案:

答案 0 :(得分:4)

$[]$(())版本基本上可以互换,但并非所有shell都支持$[],因此请勿使用它 - 请改用$(())。此外,在这两种形式中,表达式中使用的变量将自动展开,因此您无需在其中使用$

var=$RANDOM
echo $var             # prints 7482 (in my example run)
echo $[ $var % 13 ]   # prints 7
echo $[ var % 13 ]    # prints 7
echo $(( $var % 13 )) # prints 7
echo $(( var % 13 ))  # prints 7

expr实际上是一个执行表达式评估的命令 - 它具有与内置表达式评估大部分相同的功能,但没有一些细节。例如,您必须使用$来扩展变量,并且必须转义shell将其视为特殊字符的所有运算符(例如<>|等) :

expr $var % 13        # prints 7
echo `expr $var % 13` # prints 7, just by a less direct route

$()完全不同 - 它不进行算术评估,它将其内容作为命令运行。事实上,它与反引号几乎相同(除了它更容易阅读,并且语法更清晰,所以我总是使用它而不是反引号):

echo $(expr $var % 13) # prints 7, same as with backquotes

为了让这更复杂,让我添加更多选项:

(( var5 = var % 13 )) # This is an arithmetic statement (that happens to contain an assignment)
echo $var5            # prints 7
let "var6 = var % 13" # Another form for pretty much the same thing
echo $var6            # prints 7

declare -i var7  # declare var7 as an integer...
var7="var % 13"  #  to force values assigned to it to be evaluated
echo $var7       # prints 7

那么你应该用什么?为了获得最大的兼容性和(恕我直言)干净的语法,我会选择var3=$(( var % 13 ))

答案 1 :(得分:2)

$[…]$((…))完全相同。但是,$[…]表单是不推荐使用的bash和zsh扩展名; $((…))表单为standard

expr表单大致相同,但它调用外部程序expr。在过去,shell没有很多内置功能,特别是没有算术,因此可以使用expr进行算术运算。如今,expr没有多大用处。

$( $var % 13 )刚刚破解,它会尝试将$var(或者更确切地说,它的第一个单词)作为命令名称。

答案 2 :(得分:1)

无效命令

var=$( $var % 13 )

有效命令,但更喜欢$(( var % 13 ))

var=$(( $var % 13 ))

无效命令

var=$var % 13

结果:所以只有$(( var % 13 ))才能使$var的模数为13的有效方法。

<强>更新

在您进行编辑后,我会说使用var1var3计算模数的方法。 expr是一个外部程序,最好使用bash的内部实用程序来完成相同的工作。

答案 3 :(得分:1)

((var%=13))

是另一种方式,var =((var%13))

的快捷方式