问题 Bash Scripting和bc


我正在尝试编写一个bash脚本,我需要做一些浮点数学运算。基本上我想做这样的事情:

NUM=$(echo "scale=25;$1/10" | bc)
if [ $? -ne 0 ]
then
echo bad
fi

我遇到的问题是$?倾向于保持echo程序的输出而不是bc调用。有没有办法将bc程序的输出保存到变量中?

编辑:

感谢您的快速回复。这是另一种看待问题的方法。假设我稍微修改了脚本,所以看起来像这样:

#!/bin/bash
NUM=$(echo "scale=25;$1/10" | bc)
if [ $? -ne 0 ]
then
echo bad
exit
fi
echo "$NUM"

当用户输入正常的浮点值时,它可以正常工作:

bash script.sh 1.0

输出:

.1000000000000000000000000

但是,当用户输入的值不正确时,脚本无法恢复:

bash script.sh 1.0a

输出:

(standard_in) 1: parse error

我想要做的就是让它优雅地退出。


6901
2018-02-25 05:50


起源



答案:


我没有看到任何错误。 $ NUM应该是你的 bc 命令结果

看到:

NUM=$(echo "scale=25;$1/10" | bc)
echo "\$? is $?"
echo "NUM is $NUM"

产量

$ ./shell.sh 10
$? is 0
NUM is 1.0000000000000000000000000

另一种方法是使用awk

NUM=$(awk -vinput="$1" 'BEGIN{printf "%.25f", input/10 }')
echo "\$? is $?"
echo "NUM is $NUM"

另一种方法是在你转到之前检查“$ 1” bc。例如

shopt -s extglob
input="$1"
case "$input" in
 +([0-9.]))
     IFS="."; set -- $input
     if [ $# -ne 2 ];then
        echo "bad decimal"
     else
        NUM=$(echo "scale=25;$1/10" | bc  )
        echo "$NUM"
     fi
esac

你不必检查 $? 从 bc 再


8
2018-02-25 05:59



请记住,'NUM为$ NUM'的成功回显会覆盖$中的值吗?来自'$(echo ... | bc)'命令。 - Jonathan Leffler
是的,谢谢你的纠正。 - ghostdog74
我澄清了上面的帖子。感谢awk的提示。如果我不能让bc工作,我将不得不检查出来。 - LandonSchropp
另一种方法是在传递之前将输入$ 1清理为小数或数字 bc。看我的编辑。 - ghostdog74
这是一个切肉刀检查,但有没有办法确保只有一个'。'人物存在?谢谢。 - LandonSchropp


答案:


我没有看到任何错误。 $ NUM应该是你的 bc 命令结果

看到:

NUM=$(echo "scale=25;$1/10" | bc)
echo "\$? is $?"
echo "NUM is $NUM"

产量

$ ./shell.sh 10
$? is 0
NUM is 1.0000000000000000000000000

另一种方法是使用awk

NUM=$(awk -vinput="$1" 'BEGIN{printf "%.25f", input/10 }')
echo "\$? is $?"
echo "NUM is $NUM"

另一种方法是在你转到之前检查“$ 1” bc。例如

shopt -s extglob
input="$1"
case "$input" in
 +([0-9.]))
     IFS="."; set -- $input
     if [ $# -ne 2 ];then
        echo "bad decimal"
     else
        NUM=$(echo "scale=25;$1/10" | bc  )
        echo "$NUM"
     fi
esac

你不必检查 $? 从 bc 再


8
2018-02-25 05:59



请记住,'NUM为$ NUM'的成功回显会覆盖$中的值吗?来自'$(echo ... | bc)'命令。 - Jonathan Leffler
是的,谢谢你的纠正。 - ghostdog74
我澄清了上面的帖子。感谢awk的提示。如果我不能让bc工作,我将不得不检查出来。 - LandonSchropp
另一种方法是在传递之前将输入$ 1清理为小数或数字 bc。看我的编辑。 - ghostdog74
这是一个切肉刀检查,但有没有办法确保只有一个'。'人物存在?谢谢。 - LandonSchropp


对于GNU bc,将在stderr上输出类似于“(standard_in)1:语法错误”的错误。您可以在变量中捕获它并检查它。

#!/bin/bash
NUM=$(echo "scale=25;$1/10" | bc 2>&1)
if [[ $NUM =~ error || $? -ne 0 ]]
then
    echo bad
    exit
fi
echo "$NUM"

2
2018-02-25 07:46





您是否在bc(存储在NUM中)的计算结果或系统调用的状态返回后?

正如我所说,你有计算结果 $NUM

#bctest.sh
NUM=$(echo "scale=25;$1/10" | bc)
if [ $? -ne 0 ]
then
echo bad
fi

echo "result: ", $NUM

测试:

bash ./bctest.sh 15
result: , 1.5000000000000000000000000

1
2018-02-25 06:01



我试图从系统调用中获取状态返回。对不起,我应该更明确。 - LandonSchropp