如何在 bash while 循环条件语句中使用 bc?

How to use bc in a bash while loop condition statement?

我正在编写一个简单的 bash 脚本来计算公式 C=1-(p^n) 中需要的最小值 p。 C、p为用户输入,为浮点数。

例如,如果 C=0.36 和 p=0.8,那么我的程序应该 return 2 作为 n 的值,因为 1-(0.8^2)=0.36

我的代码如下。请注意:我在我的 while 循环条件语句中的许多不同位置放置了 |bc 并且每次我都收到错误。如您所见,我尝试的最后一个位置是在两个右括号之间。

我收到以下错误:

operand expected (error token is ".36")

#!/bash/bin

echo "Enter I/O fraction time:"
read ioINPUT
echo "Enter expect CPU utilization:"
read uINPUT
n=1

function cpuUTIL {
    x='scale=3; 1-$ioINPUT**$n'|bc
}

while [[ cpuUTIL -lt $uINPUT ]|bc]; do
    n+=1
    x='scale=3; 1-$ioINPUT**$n'|bc
done
echo $c

如何在 bash 脚本 while 循环条件语句中正确使用 bc?

您可以迭代并找到一个值,但为什么呢?这是一个更好的方法

awk -v p=0.8 -v C=0.36 'BEGIN{print log(1-C)/log(p)}'

也会取值,一般浮点数,可以用int()

包裹对数比得到floor

评论中指出了一些问题。这是您尝试的修复版本:

#!/bin/bash

cpuUTIL () {
    bc <<< "scale = 3; 1 - $ioINPUT ^ $n"
}

read -p "Enter I/O fraction time: " ioINPUT
read -p "Enter expect CPU utilization: " uINPUT
n=1

while (( $(bc <<< "$(cpuUTIL) < $uINPUT") )); do
    (( ++n ))
    x=$(bc <<< "scale = 3; 1 - $ioINPUT ^ $n")
done

echo $x

评论:

  • #!/bin/bash,不是#!/bash/bin
  • echoread 可以缩短为 read -p
  • function cpuUTIL 不如 cpuUTIL ()
  • 便携
  • 单引号防止参数扩展;你必须为你的 bc 命令使用双引号
  • 我在这里使用字符串 (<<<) 而不是管道以避免创建子 shell
  • "Power of" 在 bc 中是 ^ 而不是 **
  • while 条件很复杂:在 (( )) 中使用嵌套命令替换,它将 bc 语句的输出(如果比较成立则为 1,否则为 0)转换为true/false 对于 Bash
  • n+=1 将字符串 1 附加到变量 n 的内容中(除非它被声明为带有 declare -i 的整数,但这是相当奇特的),所以你必须使用类似算术上下文的东西,(( ++n ))
  • 最后的说法大概应该是echo $x

但是,如 所示,您可以直接执行此操作。在公元前,它看起来像这样:

$ p=0.8
$ C=0.36
$ bc -l <<< "scale = 3; l(1-$C) / l($p)"
2.000

bc -l 定义数学库,其中包含(除其他外)自然对数 l(x).

使用 GNU bc:

#!/usr/bin/bc -ql
scale=3
print "Enter I/O fraction time: "
p=read()
print "Enter expected CPU utilization: "
c=read()
l(1-c)/l(p)
quit

将上面的内容保存到foo.bc,运行chmod +x foo.bc,然后用./foo.bc.

执行

或没有提示,来自bash

bc -l <<< "p=0.8;c=0.36;scale=3;l(1-c)/l(p)"