在 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
我尝试了很多变体,以便可以增加变量 short、long 和 ratio 具有浮点值。我知道我无法处理 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"
的输出),然后将其输出(没有)通过管道传输到 bc
。 bc
的输出(如果有的话)将打印到终端而不是被捕获。
总而言之,您应该像这样替换每一行:
ratio= `echo $ratio + $step` | bc
像这样:
ratio=$(echo "$ratio + $step" | 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 具有浮点值。我知道我无法处理 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"
的输出),然后将其输出(没有)通过管道传输到 bc
。 bc
的输出(如果有的话)将打印到终端而不是被捕获。
总而言之,您应该像这样替换每一行:
ratio= `echo $ratio + $step` | bc
像这样:
ratio=$(echo "$ratio + $step" | bc)