在Shel的浮点数学中未成功使用bc

时间:2019-02-04 22:01:24

标签: bash bc

#!/bin/bash
    step=0.05
    short=0.05
    long=0.95
    for firstloop in {1..20}; do
        ratio=0.05
        for secondloop in {1..20} ; do
            echo $short $long $ratio >> file.txt
            time python3 main.py $short $long $ratio >> file.txt
            ratio= `echo $ratio + $step` | bc
        done
        short= `echo $short + $step`| bc
        long= `echo $long + $step`| bc

    done

当我执行代码时,这就是我得到的:

./script.sh: line 10: 0.05: command not found

real    0m25.329s
user    0m24.770s
sys 0m0.263s
./script.sh: line 10: 0.05: command not found

real    0m34.666s
user    0m32.319s
sys 0m0.623s
./script.sh: line 10: 0.05: command not found

real    0m31.425s
user    0m29.329s
sys 0m0.588s
./script.sh: line 10: 0.05: command not found

我尝试了多种变体,以便可以使用浮点值递增变量 short long ratio 。我知道除非使用 bc ,否则我无法处理shell中的浮点数学运算。我仍然没有成功。我在做什么错了?

按照下面的答案中的说明修复空格错误和bc格式后。我留下了这个输出:

real    0m0.871s
user    0m0.497s
sys 0m0.166s
++ echo '0 + 0.05'
++ bc
+ ratio=.05
+ for secondloop in '{1..20}'
+ echo 0 1 .05
+ python3 main.py 0 1 .05
Traceback (most recent call last):
  File "main.py", line 46, in <module>
    main()
  File "main.py", line 17, in main
    probability = [float(x) for x in sys.argv[:2]]
  File "main.py", line 17, in <listcomp>
    probability = [float(x) for x in sys.argv[:2]]
ValueError: could not convert string to float: 'main.py'

这基本上是我在3变量的值更改时反复得到的结果。

1 个答案:

答案 0 :(得分:2)

首先,我将提出一种样式建议:使用$( )代替反引号。它们几乎是等效的,只是它们更易于阅读并且语法更简洁(在反引号内部使用转义符或嵌套反引号是……很奇怪)。另外,通常最好在变量引用周围加上双引号(例如,使用python3 main.py "$short" "$long" "$ratio"代替python3 main.py $short $long $ratio)。

现在,真正的问题是:首先,您不能在作业中的=周围放置空格,否则它将被解析为完全不同的东西。通常,空格是shell语法中的关键分隔符,复制示例时,您不应添加或删除它们。

比较以下命令:

ratio=0.05
ratio= 0.05
ratio = 0.05

第一个操作看起来像-将变量ratio设置为“ 0.05”。第二个等效于ratio='' 0.05 -它尝试将命令“ 0.05”运行,并将变量设置为空字符串。这就是您的脚本正在执行的操作,这就是为什么会出现错误“ 0.05:找不到命令”的原因。第三个命令尝试将“ ratio”作为命令运行,并向其传递参数“ =“和“ 0.05”。

第二个问题是您在捕获外部拥有到bc的管道。比较这些命令:

ratio=$(echo "0.05 + 0.05" | bc)
ratio=$(echo "0.05 + 0.05") | bc

第一个作为管道运行echo "0.05 + 0.05" | bc,然后捕获输出并将其存储在变量ratio中。这就是你想要的。第二组将ratio设置为“ 0.05 + 0.05”(echo "0.05 + 0.05"的输出),然后将其输出(不存在)通过管道传输到bcbc的输出(如果有)将被打印到终端上,而不是被捕获。

总而言之,您应该像这样替换每一行:

ratio= `echo $ratio + $step` | bc

具有这样的内容:

ratio=$(echo "$ratio + $step" | bc)