我目前正在学习 bash 脚本的世界。我知道 bash 本身不能对浮点整数进行算术运算。我做了一些研究,发现有一些工具可以帮助完成这项工作。我决定使用bc
计算器工具。唯一的问题是语法。我能够得到结果,但不是按照我想要的方式。我该如何分配数学$N_RESULTS
运算的值?
//I get arithmetic error with this syntax
DECI=128.17333
let "N_RESULTS = ($DECI - 1) / 10 + 1" | bc -l
echo $N_RESULTS
_
//I get correct results if do something like this
DECI=128.17333
echo "($DECI - 1) / 10 + 1" | bc -l
答案1
N_RESULTS=$( echo "($DECI - 1) / 10 + 1" | bc -l )
什么let
是
考虑:
let "N_RESULTS = ($DECI - 1) / 10 + 1" | bc -l
该管道有两个部分。第一个是 shell 的let
命令。由于|
符号,命令的输出let
被传递到bc
命令的标准输入。虽然 'let
能够执行整数运算并可以为变量赋值,但它不会产生任何输出。因此,即使它运行正确,也不会将任何内容传递给bc
。
以下是一个有效命令的示例let
:
$ let "result = (123 - 1) / 10 + 1"
$ echo $result
13
但是,如果我们提供一个浮点参数,则会导致错误:
$ let "result = (123.0 - 1) / 10 + 1"
bash: let: result = (123.0 - 1) / 10 + 1: syntax error: invalid arithmetic operator (error token is ".0 - 1) / 10 + 1")
该let
命令与 shell 的其余部分一样,仅执行整数运算。
什么bc
是
bc
进行浮点运算并可用于分配和操作变量:
$ echo "result = (123.0123 - 1) / 10 + 1; print result" | bc -l
13.20123000000000000000
但请注意,上述内容本身不会创建任何 shell 可用的变量。 的定义在 完成处理result
时到期bc
。为了将值传回 shell,我们需要执行 shell 变量赋值,例如:
$ result=$(echo "(123.0123 - 1) / 10 + 1" | bc -l )
$ echo $result
13.20123000000000000000
该$(...)
构造称为命令替换。它运行一个命令(在本例中为 echo 和 bc 管道),并将其标准输出放在命令行上,并在那里将其分配给变量result
。
顺便提一下,通常认为使用小写名称作为 shell 变量的最佳实践。系统的 shell 变量都是大写的,您肯定不希望意外覆盖其中一个变量。
相当于bc
什么[[ $offset -lt $result ]]
shelltest
命令(包括[
和[[
)会生成一个有用的退出代码,可用于if
、while
和其他上下文(例如&&
和 )||
,其中退出代码用于确定程序流。 bc
不会模拟该行为。它对0
任何成功的计算返回退出代码。如果发生错误,它会返回非零退出代码。以下示例展示了如何在 的帮助grep
下bc
设置有用的退出代码。
在 GNU 中bc
,关系表达式的值为1
真,0
值为假。因此,要测试是否offset
小于result
,我们只需检查是否bc
返回0
或1
。这里,grep
用于检查的输出bc
并设置适当的返回代码,该代码可用于if
、while
或 shell 将测试返回代码的其他地方。例如:
$ offset=1.25; result=1.33
$ echo "$offset < $result" | bc -l | grep -q 1 && echo yes || echo no
yes
$ offset=1.35
$ echo "$offset < $result" | bc -l | grep -q 1 && echo yes || echo no
no
在非 GNU 下bc
,可以做同样的事情,但if
需要一个正式的声明:
echo "if ($offset < $result) print 1 else print 0 " | bc -l | grep -q 1 && echo yes || echo no