【问题标题】:How to run f(x) inside a loop which entered by the user如何在用户输入的循环中运行 f(x)
【发布时间】:2021-03-29 21:02:35
【问题描述】:

我正在尝试在 for 循环中运行 f(x),此时 f(x) 将由用户插入。 例如 f(x)=(x^2-4)/(x-2)。当我在循环中输入完整的 f(x) 时,它起作用了。但是,当我尝试使用变量时,它不起作用。

F='(${X}^2-4)/(${X}-2)'
for X in 3 4; do
    echo "${F}" | bc # this doesn't work
    echo "(${X}^2-4)/(${X}-2)" | bc # this one works
done
exit 0

【问题讨论】:

  • 还有两个进入bash 的技巧: 1) shellcheck.net 对您的代码进行静态分析,并通过遵循最佳实践帮助您避免许多陷阱; 2)您可以使用bash -x yourScript.sh 或在脚本中添加set -x 来调试bash 脚本:它会使bash 在执行时显示每个命令,但在它们展开之后。 (我在第一条评论中的意思是“文本”,而不是“测试”;可悲的是不能再编辑它了)
  • 嗨亚伦,再次感谢。问题是我假设我不知道 f(x) 并且脚本会提示用户输入它。 (我的意思是你提出的文本解决方案)

标签: bash loops for-loop variables


【解决方案1】:

您将希望您的用户提供包含数学变量的表达式,而不是 bash 变量,然后构造一个 bc 命令,该命令将在评估函数之前根据您的 bash 变量对这些数学变量进行赋值:

F='(x^2-4)/(x-2)'
for X in 3 4; do
    echo "x=$X; $F" | bc
done

你可以try it here

在您的代码中,函数变量不起作用,因为您将其定义在单引号中,这意味着 bash 变量没有展开,bc 收到 $X 而不是它的值。 使用双引号可能有效,但需要在函数之前定义 bash 变量。

此外,扩展包含 bash 变量的用户提供的函数将需要使用 eval 或类似的技巧来评估可能构成安全威胁的任意用户提供的代码。

【讨论】:

  • 这可能被认为比我的答案更干净,但是问题被标记为“bash”,所以我认为 OP 想要一个 bash 解决方案。
  • @ternary 我不使用比 OP 的代码更多的二进制文件,所以我认为这不是问题。不过,答案越多越好:)
  • 嗨亚伦,是的!你说的对!我的意思是在 Bash 中。有用。非常感谢!
【解决方案2】:

bash shell 只应用一个变量扩展通道,因此 X 必须在子 shell 中扩展。可以这样做:

F='(${X}^2-4)/(${X}-2)'
for X in 3 4; do
    (
        echo "X=${X}"
        echo 'echo "'"${F}"'"|bc'
    )|
    bash
done

将不受信任的代码传递到 shell 中的安全考虑,正如它们在 cmets 中所表达的那样,当然适用。我的示例尚未检查是否正确引用了 F 的任意值,因此只能将其视为如何使用 shell 完成此操作的草图。

【讨论】:

  • 嗨,该解决方案也解决了问题。非常感谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多