在 shell 的浮点数学中使用 bc 不成功

unsuccessful use of bc in float point math in shel

#!/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

我尝试了很多变体,以便可以增加变量 shortlongratio 具有浮点值。我知道我无法处理 shell 中的浮点数数学,除非我使用 bc。我还没有成功。我做错了什么?

修复空格错误和 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 变量的值发生变化时反复得到的结果。

首先,我将提出一个风格建议:使用 $( ) 而不是反引号。它们大部分是等价的,只是它们更易于阅读并且语法更简洁(在反引号内使用转义符或嵌套反引号是......奇怪)。此外,在变量引用周围加上双引号通常是个好主意(例如,使用 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

首先运行s 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)