【问题标题】:unsuccessful use of bc in float point math in shel在 shell 中的浮点数学中使用 bc 失败
【发布时间】:2019-02-04 22:01:23
【问题描述】:
#!/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。我知道除非我使用 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 变量的值发生变化时反复得到的。

【问题讨论】:

  • 在做任何赋值时不要使用空格a=1是正确的,a = 1是不正确的。
  • @PS。感谢您的意见。
  • Shellcheck 发现此代码存在多个问题。
  • @pjh 没有检测到拼写检查问题
  • 这是Shellcheck,而不是“拼写检查”。 Shellcheck 对代码发出 14 条警告,就像现在一样。

标签: bash bc


【解决方案1】:

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

【讨论】:

  • 我添加了修改,现在我有了:“ValueError: could not convert string to float: 'main.py'” 我觉得 bc 的语法仍然不正确!
  • 在这种情况下,准确了解正在传递的值非常重要。将set -x 放在此部分之前(并在其后设置`set +x),它会在运行时打印它正在执行的命令的等价物。
  • 值在逻辑上进展。 main.py 文件的执行虽然没有发生,因为它仍然认为它们是一个字符串,因此只返回错误: ValueError: could not convert a string to float: 'main.py' !!!!
  • 等等,它正在尝试将字符串“main.py”转换为浮点数?这里还有其他问题——要么您将其他内容传递给 python 脚本,要么它对如何获取其参数感到困惑。
  • 这个想法是使用不同的输入多次运行文件 main.py:$ratio$short$很长 这就是为什么脚本应该很方便!我不明白字符串来自哪里,因为脚本中的变量显然是浮点数!
猜你喜欢
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多