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

发布于 2024-11-06 21:43:26 字数 556 浏览 1 评论 0原文

我刚刚发现了这个很棒的网站。当我阅读 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 语句不起作用。我的问题是:使用其他三个中的哪一个只是个人选择的问题,还是还有其他需要考虑的因素?

(在看到回复后,我对这个问题进行了广泛的编辑。希望我以正确的方式做到这一点。)

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

枯寂 2024-11-13 21:43:26

$[]$(()) 版本本质上是可以互换的,只是并非所有 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 )) 以获得最大的兼容性和(恕我直言)干净的语法。

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.

避讳 2024-11-13 21:43:26

$[…]$((…)) 完全相同。但是,$[…] 形式是已弃用的 bash 和 zsh 扩展; $((…)) 形式是 标准

expr 形式大致相同,但它调用外部程序 expr。在过去,shell 没有很多内置功能,特别是没有算术,因此人们会使用 expr 进行算术。如今,expr 已经没有太多用处了。

$( $var % 13 ) 刚刚被破坏,它尝试调用 $var (或更准确地说,它的第一个单词)作为命令名称。

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.

等风也等你 2024-11-13 21:43:26

无效命令

var=$( $var % 13 )

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

var=$(( $var % 13 ))

无效命令

var=$var % 13

结果: 因此,只有$(( var % 13 )) 是获取 $var 以 13 为模的有效方法。

更新

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

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.

梦途 2024-11-13 21:43:26
((var%=13))

另一种方式是 var=((var%13)) 的快捷方式

((var%=13))

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文