【问题标题】:different calculation results using bc in script and console在脚本和控制台中使用 bc 的不同计算结果
【发布时间】:2011-02-19 12:40:09
【问题描述】:

在我现在编写的脚本中,我需要一些十进制计算,所以我决定使用bc。我不熟悉这个工具,如果问题是微不足道的,请原谅我。
当我使用控制台并输入:

set r_m=`echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3)) +$pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l`

然后echo "$r_m" 它给了我: 19.849870
($pd_f 和 $d_f 之前分别声明了 1.129 和 1.126,哦和 $fr_numb=18)

but(!) 在 bash 脚本中使用相同的行:

r_m=`echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3))+ $pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l`

给我: .033022

为什么?

更新 我将= 之后的所有内容都用反引号括起来。我之前不知道如何在 blockquote 中使用它们。

外壳是 bash 2.05

【问题讨论】:

  • 什么 shell 使用你的 console?如果我输入您的示例,它会给我(standard_in) 1: syntax error(四次)。那么,变量$pd_f$d_f$fr_numb 具有哪些值?
  • @Paŭlo Ebermann:我已经更新了这个问题。它现在不应该给你语法错误。正如我所说,这些变量是较早设置的,并且是简单的数字。

标签: bash bc


【解决方案1】:

这个脚本

#!/bin/bash

pd_f=1.129
d_f=1.126
fr_numb=18

r_m=`echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3))+$pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l`

echo $r_m

上输出 19.849870
GNU bash, Version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.

就像在(bash 驱动的)控制台上输入时的输出一样。也许您需要在调用脚本之前导出变量,如果它们没有在脚本中定义,而只是在周围的 shell 中?

【讨论】:

  • 如果我从控制台运行方程,我会在计算之前在控制台中设置变量。如果我在脚本中运行它,我也会在之前设置 $pd_f、$d_f 和 fr_numb。
  • 哦,我又检查了一遍,发现 fr_numb 被错误地声明了。现在很好。谢谢
【解决方案2】:

fr_numb=0 时我得到结果 .033022。

顺便说一句,您的交互式命令显然是在 csh 中运行的。如果您想确保脚本由 Bash 运行,则应确保脚本的第一行包含以下内容:

#!/bin/bash

此外,请使用一些空格和续行以使您的公式更具可读性。

#!/bin/bash
pd_f=1.129
d_f=1.126
fr_numb=18
fr_numb=0
r_m=$(echo "scale=6; \
    $pd_f*$d_f * (1 / sqrt(3)) + \
    ($fr_numb - 1) * ( \
        $pd_f * $d_f * (1 / sqrt(3)) + \
        $pd_f * $d_f * 0.5 * \
        ( \
            s(3.14159265 * 30 / 180) / c(3.14159265 * 30 / 180) \
        ) \
     ) + \
     0.4 " | bc -l)

顺便说一句,在发布问题时,发布变量分配,以便它们可以轻松复制,以便可以复制您的设置,而不是像“($pd_f 和 $d_f 之前分别声明为 1.129 和 1.126,哦和 $fr_numb=18)" 需要大量编辑才能使用。

【讨论】:

  • 感谢您的建议,我会努力坚持下去的。
【解决方案3】:

如果您在 shell 中设置了 3 个变量,例如:

pd_f=1
d_f=2
fr_numb=3

然后你运行原来的命令:

set r_m=`echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3))+$pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l`

那么你最终会将$1 设置为r_m=5.018798(并且所有其他位置参数都未定义)。这是因为在bash 和所有其他 Bourne shell 派生类中,set 语句用于调整 shell 选项或设置位置参数的含义,$1$2、...等(但不是 @ 987654329@).

如果您没有这三个变量的值,则会得到bc 诊断的语法错误。

特别注意,原始命令没有设置变量r_m;这只会在 C shell 或 C shell 派生中设置变量。 shell 变量$r_m 完全不受set 语句的影响。您在 $r_m 中看到的结果是您之前实验中遗留在变量中的任何内容。

另一方面,当你运行时:

r_m=`echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3))+$pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l`

那么您将分配给变量r_m

【讨论】:

    【解决方案4】:

    用 $() 括住你的命令

    r_m=$(echo "scale=6; $pd_f*$d_f*(1/sqrt(3))+($fr_numb-1)*($pd_f*$d_f*(1/sqrt(3))+$pd_f*$d_f*0.5*(s(3.14159265*30/180)/c(3.14159265*30/180)))+0.4"|bc -l)
    

    【讨论】:

    • 好吧,事实是它包含在 `` 中,但我不知道如何将反引号插入块引号中。 $() 没有帮助。
    • $() 在 Stackoverflow 上更容易输入(显示),这是使用它的一个原因。另一个原因是,当您有多个级别时,更容易看到嵌套。不过,它对您的问题没有任何帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    相关资源
    最近更新 更多