如何在Linux Shell中对变量进行除法?


136

当我在外壳中按以下方式运行命令时,它将返回expr: non-integer argument错误。有人可以向我解释一下吗?

$ x=20
$ y=5
$ expr x / y 
expr: non-integer argument

4
@ShivanRaptor虽然有人可能会说这个问题是RTFM问题,但它无疑是一个有效的shell编程问题。对于来自不需要取消引用的语言(例如Ruby或JavaScript)的人来说,这也是一个合理的问题。它应该保持打开状态。
Todd A. Jacobs

6
@ShivanRaptor不,这是这里的话题。这是关于在Bash中编程。Unix / Linux主要用于使用系统,而不用于编程。现在,shell脚本确实跨越了编程和使用系统之间的边界,因此这可能是这两个站点上的主题。如果对“我如何设置网络”存在疑问,那肯定属于Unix / Linux。如果是关于Bash中的交互式键绑定的问题,那么它也应该属于那里。但是关于shell脚本编写的问题肯定是这里和那里的话题。
布莱恩·坎贝尔

见我的答案在这里,那说明$ BASH变量的减法和除法,使用Python的呼叫从外壳(将int转换成浮动...):stackoverflow.com/questions/8385627/...
维多利亚斯图尔特

Answers:


195

这些变量是外壳变量。要将它们作为参数扩展到另一个程序( expr),您需要使用$前缀:

expr $x / $y

它抱怨的原因是因为它认为您试图对字母字符进行操作(非整数)

如果您使用的是Bash shell,则可以使用表达式语法实现相同的结果:

echo $((x / y))

要么:

z=$((x / y))
echo $z

1
通过阅读bash的手册页,您可以了解很多内容。键入man bash在提示符(q退出)
水稻

62
必须在此页面的某处指出,大多数(如果不是全部)GNU / Linux外壳程序仅执行整数运算
Skippy le Grand Gourou 2014年

35

我相信其他线程已经提到了它:

calc(){ awk "BEGIN { print "$*" }"; }

然后您可以简单地输入:

calc 7.5/3.2
  2.34375

在您的情况下,它将是:

x=20; y=3;
calc $x/$y

或者,如果愿意,可以将其添加为单独的脚本,并使其在$ PATH中可用,以便始终将其保存在本地shell中:

#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }

4
您也可以使用echo '1 / 3' | bc -l
尤金(Eugene)2017年

19

为什么不使用let; 我发现这要容易得多。这是一个您可能会发现有用的示例:

start=`date +%s`
# ... do something that takes a while ...
sleep 71

end=`date +%s`
let deltatime=end-start
let hours=deltatime/3600
let minutes=(deltatime/60)%60
let seconds=deltatime%60
printf "Time spent: %d:%02d:%02d\n" $hours $minutes $seconds

另一个简单的示例-计算自1970年以来的天数:

let days=$(date +%s)/86400

15

引用Bash变量需要参数扩展

大多数Linux发行版上的默认Shell是Bash。在Bash中,变量必须使用美元符号前缀进行参数扩展。例如:

x=20
y=5
expr $x / $y

当然,Bash还具有算术运算符和特殊的算术扩展语法,因此无需将expr二进制文件作为单独的进程来调用。您可以让Shell像这样完成所有工作:

x=20; y=5
echo $((x / y))

有关所有详细信息,请参见Bash参考手册中的算术扩展Shell算术
Todd A. Jacobs

1
这有没有关系非关联化,但插值expr在2013年被劝阻
吉尔斯Quenot

@sputnick你显然很困惑。请随时查阅字典。请参阅取消引用内插
托德·雅各布斯

1
一个更好的词正在扩展,而不是取消引用。当我们使用指针时,会使用dereferencing,这里不是这种情况,那只是简单的变量。
吉尔斯·奎诺

1
@Prashant:在bash世界中,不知道tldp是一个很好的参考。
吉尔斯·奎诺

1

假设

x=50
y=5

然后

z=$((x/y))

这将正常工作。但是,如果要在case语句中使用/运算符,则无法解析它。 在这里输入代码 在这种情况下,请使用简单的字符串,例如div或devide或其他名称。看代码


错了 /可以很好地用作外壳标签。不起作用的是在*不加引号的情况下使用乘法,这可能是您实际上所做的。会导致它有效地覆盖该情况下的所有以下项,在您的示例中为“ devide”和“ modulo”
dave_thompson_085

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.