bc: 防止 "divide by zero" 多个操作的运行时错误

bc: prevent "divide by zero" runtime error on multiple operations

我正在使用 bc 进行一系列计算。

我通过一个 bash 脚本调用它,该脚本首先将所有要计算的表达式放在一个变量中,然后将它们传递给 bc 以计算结果。

脚本是这样的:

#!/bin/bash
....

list=""

for frml in `cat $frmlList`
do
    value=`echo $frml`
    list="$list;$value"
done

echo "scale=3;$list"| bc

frmlList 变量包含一个表达式列表,这些表达式是另一个程序的输出,为简单起见,我没有提到每个操作,但是在将其分配给 [=41= 之前对其内容进行了一些 sed 操作]变量。

最后,"list" 变量包含 bc 理解的以分号分隔的表达式列表。

现在发生的事情是,在我的公式列表中,有时会出现被 0 除的情况。

当它发生时 bc 停止计算并给出 "Runtime Error: divide by zero".

我不希望结束针对该错误的工作,而是跳过它并继续进行下一个公式评估。

有可能实现这样的目标吗?

同样的事情发生在更简单的情况下:

echo "scale=2;1+1;1/0;2+2;" | bc

输出是

2
Runtime error (func=(main), adr=17): Divide by zero

我想要类似的东西

2
Runtime error (func=(main), adr=17): Divide by zero
4

提前谢谢你:)

我不知道有什么简单的方法可以做到这一点。如果表达式是独立的,你可以尝试运行它们都在bc中。如果失败,将它们一个接一个地喂给 bc,跳过损坏的。

如果表达式相互依赖,那么您可能需要比 bc 更强大的东西。或者您可以尝试将表达式追加到输入文件中。如果 bc 失败,删除最后一个(可能从备份中恢复文件)并尝试下一个。

好的,最后我找到了一个非常有效的解决方法。

想法是使用子 shell 并行执行 bc,这样如果评估失败,另一个仍然可以完成。

在我的脚本中我做了这样的事情:

#!/bin/bash
i=0

for frml in `cat $frmlList`
do
    i=$((i+1))
    (echo "scale=3;$value"| bc -l extensions.bc > "file_$i.tmp") &

    if (( $i % 10 == 0 )); then
      wait;
    fi # Limit to 10 concurrent subshells.
done

#do something with the written files