有没有适用于Ubuntu的命令行计算器?

我正在寻找一个可以在终端自身进行计算的计算器,不需要任何额外的前缀和后缀。
例如:如果我在终端中输入10000-9000,答案应该是1000。
再次强调,我只需要一个快速的终端计算器,不需要添加任何字符。我知道如果切换到Python,它可以做到这一点,但我不想以这种方式使用它。

1或许你可以尝试访问http://packages.ubuntu.com/saucy/apcalc - wakeup
2可能可以通过一种预先挂钩的方式来实现类似的操作;但这本身只能以一种非常丑陋和不专业的方式完成。我非常认为这不是一个好主意。Bash作为一个纯粹的IO脚本语言,除此之外的任何功能都是或多或少的临时性的,并且并不工作得很好。另一方面,Python(甚至是Haskell等)是一种现代化、通用的编程语言,具有出色的语法。因此,不使用它将是愚蠢的决定。 - leftaroundabout
3在同样的思路下,你也可以利用command_not_found钩子来处理,如果命令看起来像是数学相关的,尝试将其传递给bc/calc或其他类似的工具。不过,这种方法仍然有些不太正规。 - chronitis
1等一下,你究竟是什么意思说“切换到”Python?还有“没有任何额外前缀”?你是说你想在提示符中进行计算,而不运行命令吗? - Random832
1我不明白。为什么你不能使用Python?你是想在Bash中直接输入10000-9000,而不运行任何程序或输入其他命令吗? - jumpnett
@Random832 计算 2+3,这里的 "calc" 在我看来是前缀。使用 echo "scale = 3; 0.1-0.09" | bc 这里的 "|" 是后缀。有什么问题吗? - Raja G
@jumpnett 只需通过终端,无需其他程序或Python。 - Raja G
2http://unix.stackexchange.com/questions/40786/how-to-do-integer-float-calculations-in-bash-or-other-languages-frameworks - Bernhard
@Bernhard,那真是太棒了。 - Raja G
另请参阅:https://unix.stackexchange.com/questions/480121/simple-command-line-calculator - Matthias Braun
25个回答

您可以使用calc。它不是默认安装的,但是您可以使用以下命令快速安装:

sudo apt-get install apcalc

安装完成后,您可以进行任何所需的计算。
$ calc 5+2
    7
$ calc 5-2
    3
$ calc 5*2          
    10
$ calc 5/2
    2.5
$ calc 5^2
    25
$ calc 'sqrt(2)' 
    1.4142135623730950488
$ calc 'sin(2)'
    0.9092974268256816954
$ calc 'cos(2)'
    -0.416146836547142387
$ calc 'log(2)'
    ~0.30102999566398119521
$ calc 'sqrt(sin(cos(log(2))))^2'
    ~0.81633199125847958126
$ # and so on...

如需更多信息,请查看其man-page

2谢谢你的回答,我明白答案有其独特的意义。我更喜欢一些关于三角函数计算的内容。如果有关于它更多用途的手册或网页,可以大大提升你的回答。:) - Raja G
@rajagenupula man calccalc help说得很清楚了。 - Radu Rădeanu
2我的意图是,如果有人看到它,应该清晰而迅速。谢谢。 - Raja G
1实际上,你可以使用calc help builtin来查看支持的函数列表,比如sin() - Penghe Geng
提供更多的小数位,因此比内置的 Bash 算术更适合我的用途。谢谢。 - Mrmfldmn

你可以在bash中使用((...))语法进行简单的整数运算,例如:
$ echo $((10000-9000))
1000

还有一个名为bc的计算器,它可以接受标准输入上的算术表达式。
$ echo "10000-9000" | bc
1000

bc程序也可以进行浮点数算术运算。

$ echo "scale = 3; 0.1-0.09" | bc
.01

11这可能是最接近的方法了。为了减少额外的输入(虽然不能完全消除),您可以将一个函数放在您的~/.bashrc文件中:calc() NL { NL echo "$@" | bc NL } 其中NL代表换行符。然后您可以输入calc 1234 + 768(输出2002),或者任何其他bc能够解释的公式。当然您可以使用任何函数名称,我只是认为calc与此功能的用途相匹配。 - user
4在我看来,Python一直比Echo更好。 - Raja G
7你也可以交互地使用bc,除非你出于其他原因需要回显:只需运行bc并键入表达式。在单独的一行上键入Ctrl-D以退出。 - Useless
如果��在翻译过程中使用了别名或其他辅助手段来进行自动表达,那将会很好。请将翻译后的文本返回。 - Raja G
@rajagenupula 将以下内容添加到你的 .bashrc 文件中calc() { echo "$@" | bc; }calc 99 + -1001 返回 -902 - Hans Z
@rajagenupula 唯一需要注意的是,* 将会扩展为当前目录的文件列表,因此尝试执行 calc 3*2 会得到 6,但执行 calc 3 * 2 则会导致解析错误。如果你真的想执行 calc 3 * 2,你可以使用转义字符 \*,即 calc 3 \* 2。其他一些特殊字符如 <>=!&| 在调用时也需要单独进行转义,例如 calc 3 \> 2 1。我还可以建议使用 calcf() { echo "$@" | bc -l; } 来进行浮点数计算,因为 bc 无法在整数和浮点数之间切换。 - Hans Z
是否$((4-5))$[4-5]之间有任何区别? - aidan
3不需要回显:无需 echobc <<< "2*2" - Bernhard
expr 1 + 2echo $((1 + 2))更容易输入,效果是一样的。(当你使用特殊的shell字符如*和括号时,差异就会显现出来,在这种情况下,你需要转义或者无论如何都要使用$((...))expr \( 1 + 2 \) \* 3或者echo $(((1 + 2) * 3))bc的额外功能包括:任意精度计算(bc <<<scale=2\;1/3得到.33);进制转换:bc <<<ibase=8;obase=16;30得到1A(八进制的30转换成十六进制是1A)。 - Lekensteyn

Bash算术

另一个可能的解决方案是为Bash的内置算术添加一个简单的函数。将其放入你的.bashrc文件中以尝试:

=() {
    echo "$(($@))"
}

所以现在,你甚至不再需要$((...)),只需要=就足够自然了。

替换

如果你想更快一些,还有另外一件事:你可以将p替换为+,将x替换为*。这样就可以实现:

=() {
    local IFS=' '
    local calc="${*//p/+}"
    calc="${calc//x/*}"
    echo "$(($calc))"
}

= 5 x 5  # Returns 25
= 50p25  # Returns 75

现在你甚至不再需要按下Shift键了,唯一需要的是在算术前面加上

十六进制输出

如果需要的话,输出可以同时显示为十进制和十六进制。(注意:使用x替代会与0x...的十六进制语法冲突)

=() {
    local answer="$(($@))"
    printf '%d (%#x)\n' "$answer" "$answer"
}

例子:

$ = 16 + 0x10
272 (0x110)

$ = 16**3 + 16**4
69632 (0x11000)

使用 bc

如果你想进行稍微高级一点的计算,你可以将其通过管道传递给 bc,像这样:

=() {
    local IFS=' '
    local calc="${*//p/+}"
    calc="${calc//x/*}"
    bc -l <<<"scale=10;$calc"
}

= 'sqrt(2)' # Returns 1.4142135623
= '4*a(1)'  # Returns pi (3.1415926532)
bc 提供的功能如下(可在 man bc 中找到):
sqrt ( expression )
       The value of the sqrt function is the square root of the expression.  
       If the expression is negative, a run time error is generated.

s (x)  The sine of x, x is in radians.

c (x)  The cosine of x, x is in radians.

a (x)  The arctangent of x, arctangent returns radians.

l (x)  The natural logarithm of x.

e (x)  The exponential function of raising e to the value x.

j (n,x)
       The Bessel function of integer order n of x.

它还支持像编程语言一样的ifforwhile和变量。不过,如果你想要写入文件,最好是将其写入文件。
请记住,它会替换函数/变量名称中的px。最好是直接删除这些替换。

使用gcalccmd

你也可以这样调用函数gcalccmd(来自gnome-calculator):
=() {
    local IFS=' '
    local calc="$*"
    # Uncomment the below for (p → +) and (x → *)
    #calc="${calc//p/+}"
    #calc="${calc//x/*}"
    printf '%s\n quit' "$calc" | gcalccmd | sed 's:^> ::g'
}

= 'sqrt(2)' # Returns 1.4142135623
= '4^4'     # Returns 256

可用的函数似乎是从源代码中直接提取的(参见源代码),==表示等效函数:
ln()
sqrt()
abs()
int()
frac()
sin()
cos()
tan()
sin⁻¹() == asin()
cos⁻¹() == acos()
tan⁻¹() == atan()
sinh()
cosh()
tanh()
sinh⁻¹() == asinh()
cosh⁻¹() == acosh()
tanh⁻¹() == atanh()
ones()
twos()

对于这个晚回复我很抱歉,但你给出的gcalccmd命令效果不太好。它显示了错误3,可能是因为那个多余的空格。然而,稍作修改后的命令对我来说完美地运行了:echo -e "$calc\nquit"| gcalccmd | sed "s:^> ::g" - udiboy1209
我使用R构建了一个科学计算器! function = { R -q --vanilla -e "$@" | grep -E '[^>](.*)' -o -x --color=never } - Morteza Milani
嗨,谢谢。这很酷。顺便说一下,你对于 'x' 的替换导致十六进制输入失败了,否则它本来是正常工作的。说到这个,我可以用 'hex' 来得到答案吗?例如: = 2 + 0x20 34 (0x22) - FractalSpace
谢谢。我同时想出了一个基于Python的解决方案:c(){ python -c "from math import *; print($*, hex($*))" } - FractalSpace
请记住,bc是一个非常非常烦人的软件。 - jwg
你的计算器不喜欢小数点,比如=2048 / 3.1 - Frank N
史诗般的回答...+1 - WinEunuuchs2Unix
有没有办法消除在参数周围加引号的需要? - Artillect
除了列出的功能外,gcalccmd还内置了欧拉常数'e'。 - Lucubrator
有人知道gcalccmd中是否有一个pi常数吗? - Lucubrator

很遗憾,没有“更简单的”方法来做这个。命令行上的交互式Python界面最适合你所需要的,因为与apcalc不同,Python已经包含在Ubuntu中。我不确定bc是否还包含在里面,然而,对于这些东西来说,Python毫无疑问是首选。
你可以在命令行上运行交互式Python界面,然后以这种方式进行数学计算。你可以将其用作你的计算器。
要做到这一点,你打开终端,输入python,然后按Enter键。
接下来,在出现的Python提示符中,你可以输入数学表达式。例如,10000 - 9000。下一行输出就是结果。

如果你的意思是,只要加载终端就可以做到这一点...

$ 10000 - 9000
1000
$

... 那么不,仅仅通过终端而没有其他任何工具是无法实现这个的,因为Bash不处理这样的数值参数。


1我确实提到过,我不想转换到Python。 - Raja G
1@rajagenupula 更新了,还包括了我在聊天中提到的东西。 - Thomas Ward
不再包括BC了吗? - Random832
1顺便说一句,当涉及到计算和类似的任务时,ipython比标准的Python shell要更加有用。 - Naftuli Kay
1默认情况下,Ubuntu(至少在16.04版本中)已经包含了BC。 - TJ Ellis

我建议你为基本的Python计算创建一个简单的函数。在你的.bashrc中可以像这样写:
calc() {
    python3 -c 'import sys; print(eval(" ".join(sys.argv[1:])))' "$@"
}

calc 5 + 5
# Returns 10

result="$(calc 5+5)"
# Stores the result into a variable

如果你想做更高级的数学运算,你可以使用下面这个导入了所有math模块函数的方法。(点击这里获取更多信息)
calc() {
    python3 -c 'from math import *; import sys; print(eval(" ".join(sys.argv[1:])))' "$@"
}

calc 'sqrt(2)'  # Needs quotes because (...) is special in Bash
# Returns 1.4142135623730951

result="$(calc 'sqrt(2)')"
# Stores the result into a variable

(注意:由于Python是一种编程语言,有些东西可能看起来很奇怪,例如用**表示乘方,用%表示取模)
或者你可以创建一个Python脚本calc
#!/usr/bin/python3
from math import *
import sys
print(eval(' '.join(sys.argv[1:])))

将其放置在包含在“PATH”变量中的目录中,并设置其可执行标志,以获得与上述相同的“calc”命令(无需创建用于运行Python脚本的Bash函数)。
如果您想要一个纯Bash方法,请使用steeldriver的答案。此答案只在您需要更高级功能(即来自"math")时真正有益,因为与Bash相比,Python相对较慢。
我不确定这是否违反了你的“切换到Python可以做到这一点,而且我不希望以这种方式进行”的说明,但是你不需要进入交互提示符,结果在Bash中是可访问的,所以这个答案似乎是有效的(至少对我来说是这样)。

每次所有这些都必须意味着并不那么容易和灵活。谢谢。如果您能对其进行改进,使其更简单明了,我会很喜欢的。 - Raja G
1@rajagenupula 你可以将这个放在你的 .bashrc 文件中作为一个函数(也许可以用一个更短的名字:c? 或者 +?),这样每次打开终端时都会有它。 - kiri
1请注意:在Python 3中,这个方法非常好用,但如果你想使用Python 2,你需要编辑代码片段为:python2 -c "from __future__ import division; from math import *; print($*)",否则它将始终执行整数除法。例如,对于calc 5/2,你将得到2而不是2.5。参考链接:http://stackoverflow.com/a/183870/202504 - jmiserez
Python的解决方案实际上可能比apcalc更好,因为你可以导入额外的库,并且它支持字面量pie。我觉得将其作为一个独立的脚本更加灵活和可移植。这里有一个简单的要点:https://gist.github.com/jasongeng/279eb396c01e74beb9ef - Penghe Geng

使用gnome-calculator(>=13.04)或gcalctool(<13.04)软件包中的gcalccmd命令。我认为该软件包默认已安装。
% gcalccmd
> 2+3
5
> 3/2
1.5
> 3*2
6
> 2-3
−1
> 

到目前为止最好的一个.. 不需要额外的事情,也是默认安装的.. man gcalccmd 说:一个控制台计算器。简单来说,这正是OP想要的.. :) - Saurav Kumar
这很酷,类似于BC、Python和Octave计算器。谢谢。 - Raja G
由于"gcalccmd"很难输入,将其添加为别名到./bash_aliases中是一个好主意,如alias calc='gcalccmd'。或者,如果你想进行即时计算(带有即时答案),可以添加alias calc='gnome-calculator -s'- 后者的用法是:calc 2000/1300calc 2+3。在这种情况下,无需退出计算器 - 它会直接给出答案,无需输入quit - Rafal

另一个我在这里没有看到提到的解决方案是Qalculate (qalc)
sudo apt-get install qalc

对于CLI版本,
sudo apt-get install qalculate-gtk

对于图形用户界面(GUI)。

它具有许多功能,例如:

  • 支持单位:例如 20 m / s * 12 h = 864 kilom
  • 内置的常数,如 piecavogadro
  • 许多内置的函数:例如 sin(pi) = 0gamma(4) = 65! = 120log(1024, 2) = 10
  • 单位转换,例如:

> 120 in
120 * inch = 120 in
> convert cm
120 in = 304.8 centim

  • 符号计算,例如 (x + y)^2 = x^2 + 2xy + y^2
  • 积分,例如 integrate 3*x^2 = x^3diff sin(x), pi
  • 内置帮助,例如 help converthelp integrate
  • 命令的自动补全
  • 一切都被翻译,例如我的系统是荷兰语,所以我可以写 factorial(5)faculteit(5)
  • 等等...

你说你想要不使用前缀来使用它,嗯...你可以使用一个前缀:

$ qalc 5 ft + 3 cm (5 * foot) + (3 * centim) = 1.554 m

也可以将其作为 REPL 运行。


这个计算器功能非常齐全。它还可以解方程,进行组合数学(n选k,排列等),复数运算,矩阵运算等等。 - Madacol

这是一个快速的shell脚本:

#!/bin/bash
echo "$@" | bc

将此保存为"c",然后将其放在您的路径中(例如/bin),然后标记为可执行。
# nano /bin/c
# chmod +x /bin/c

从现在开始,你可以在终端中像这样进行计算:
$ c 10000-9000
1000

你太棒了!在计算之前只加一个字母,意味着这真是个酷炫的主意。如果我需要进行2到3次计算,这简直太方便了。我可以选择使用Python或其他更复杂的方法,但对于简单的计算,我选择这个。谢谢你的光临。 - Raja G
2我建议你使用echo "$@" | bc,这样你可以更自然地在计算中添加空格。 - kiri
使用=代替c作为该命令的名称怎么样?Bash实际上允许您将其用作函数的名称。 - Kaz
1你可以把程序放入 ~/bin (你的主目录下的 bin)中,并确保 /home/yourname/bin 在你的 PATH 中。 - Kaz
@minerz029 很好的想法。我已经相应地编辑了我的回答。 - user530873
这对于一个脚本来说可能有点过头了。如果你只是想为你的用户使用,那么在.bashrc中定义一个函数就足够了。 - kiri

这是对适当部分的修改/etc/bash.bashrc(在Ubuntu 10.04上),它将修改command_not_found处理程序,如果未知命令的第一个字符是数字或-+,则运行shell的表达式求值器。
通过这种方式,您可以进行任何shell算术运算;请参阅http://www.gnu.org/software/bash/manual/bashref.html#Shell-Arithmetic以获取算术运算符列表。
请注意,如果要评估的表达式包含*,您将需要使用\或引号引用*,因为shell会在决定要运行哪个命令之前执行文件名扩展。其他操作符如>>也是同样的情况。
将此放入您的~/.bashrc中,然后键入. ~/.bashrc并尝试一下。
# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found ]; then
    function command_not_found_handle {
        if [[ $1 == [0-9+-]* ]]; then
           echo $(( $@ ))
        elif [ -x /usr/lib/command-not-found ]; then
           /usr/bin/python /usr/lib/command-not-found -- $1
           return $?
        elif [ -x /usr/share/command-not-found ]; then
           /usr/bin/python /usr/share/command-not-found -- $1
           return $?
        else
           return 127
        fi
    }
fi

示例输出:(我正在输入cta,这是一个拼写错误,只是为了测试我们的新的命令未找到处理程序是否仍会尝试查找未知命令)。
mp@ubuntu:~$ cta
No command 'cta' found, did you mean:
 Command 'cda' from package 'xmcd' (universe)
 Command 'cat' from package 'coreutils' (main)
cta: command not found
mp@ubuntu:~$ 9000-1000
8000

有没有办法我们可以增加更多的计算支持? - Raja G
1你可以将echo $(( $@ ))这一行改为运行其他回答者提到的更高级的计算器程序之一,这些程序接受命令行参数。 - Mark Plotnick

dc!这是核心工具的一部分,所以在OS X、Ubuntu和几乎所有其他操作系统中都已安装。这是一个逆波兰计算器,所以如果你不喜欢这种类型的计算器,那它就不适合你。

非常基本的命令如下(手册中包含了我没有列出来的语法,有指数运算哦!)

只需要在数字之间加上空格即可。在其他情况下,空格将被忽略。

输入一个数字会将其推入堆栈顶部。

+ Adds top 2 items in stack, then pushes result to stack (`2 4 +p` outputs 6)
- Subtracts top 2 items in stack, then pushes result to stack (`4 2 -p` outputs 2)
* Multiplies top 2 items in stack, then pushes result to stack (`6 5 *p` outputs 30)
/ Divides top 2 items in stack, then pushes result to stack (`54 7 /p` outputs 8)
p Print top item in stack, without destroying it
c Clear stack
r Swap top 2 items on stack
d Duplicate top item on stack
k Pops top item off stack, using it to determine precision (so 10 k would print 10 numbers after the decimal point). Default is 0, so it won't do floating point math by default.
n Pops top value off stack, then sends to stdout without a trailing newline
f Dump stack. Useful for finding what something does

刚刚注意到,这并没有回答问题(其他回答也是如此)。问题是如何在方程前面(或后面)不加任何东西,只需在终端中键入例如 42 * 5,然后输出答案。 - Yet Another User
2大多数答案都不适用。在终端中输入1+1几乎永远不会起作用。所以你的答案是正确的。 - kiri
@YetAnotherUser 我认为唯一的方法就是入侵command-not-found(如果已安装)或在bashrc中做一些不正当的事情... - Braiam