开发者

Are these bash statements all equivalent?

I just discovered this great site. I was reading bash tagged posts when the following question entered my mind:

This code:

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"

Produces this output:

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

So only the var2 statement does not work. My question is: is it only a matter of personal choice as to which of the other three should be used or are there other considerations that should be taken into account?

(I've edited this question extensively after seeing replies. Hope I'm doing this the right way.)


The $[] and $(()) versions are essentially interchangeable, except that not all shells support $[], so don't use it -- use $(()) instead. Also, in both of these forms, variables used in the expression will be automatically expanded, so you don't need to use $ inside them:

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 is actually a command which does expression evaluation -- it has most of the same capabilities as the builtin expression evaluation, but without some of the niceties. For instance, you must use $ to expand variables, and must escape any operators that the shell would treat as special characters (e.g. <, >, |, etc):

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

$() is totally different -- it doesn't do arithmetic evaluation, it runs its contents as a command. In fact, it's almost the same as backquotes (except that it is easier to read, and has much cleaner syntax, so I always use it instead of backquotes):

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

And just to make this more complicated, let me add some more options:

(( 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

So what should you use? I'd go with var3=$(( var % 13 )) for maximum compatibility and (IMHO) clean syntax.


The $[…] and $((…)) are exactly equivalent. However, the $[…] form is a deprecated bash and zsh extension; the $((…)) form is standard.

The expr form is roughly equivalent, but it calls the external program expr. In the old days, shells didn't have many built-in capabilities, in particular no arithmetic, and so one would use expr for arithmetic. Nowadays there's not much use for expr.

$( $var % 13 ) is just broken, it tries to call $var (or more precisely, the first word of it) as a command name.


Invalid command

var=$( $var % 13 )

Valid command but prefer $(( var % 13 ))

var=$(( $var % 13 ))

Invalid command

var=$var % 13

Outcome: So out of all only $(( var % 13 )) is the valid way to get the modulo of $var by 13.

Update

After your edits I would say use either var1 or var3 way of getting modulo calculated. expr is an external program and its better to use bash's internal utility to get the same job done.


((var%=13))

is another way, a shortcut for var=((var%13))

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜