【问题标题】:Bash bc returns (standard_in) 1: parse error only when part of for loopBash bc 返回 (standard_in) 1:仅当部分 for 循环时解析错误
【发布时间】:2018-02-06 05:08:45
【问题描述】:

我正在遍历整数数组${startTimes}(音频文件中的标记位置,在样本中)并使用bc 将这些整数转换为毫秒。我将结果传递到一个新数组${msValuesArray}。如果我一次运行每个数组元素,它工作正常。如果我在for 循环中运行它:

for i in $(seq 0 ${#startTimes[@]}); do 
    msValuesArray+=($(bc <<< ${startTimes[i]}/44.1))
done

生成的${msValuesArray} 包含预期结果,但终端输出(standard_in) 1: parse error

虽然我打算在 shell 脚本中使用它,并且在阅读了此处的其他问题后,我了解到在命令的开头添加 #!/bin/bash 可以避免解析错误,但我仍然不明白以下内容:

a) 为什么手动将 ${startTimes} 元素传递到 bc 时不会出现解析错误,而 for 循环也可以工作,但会输出解析错误(在 shell 脚本之外)?

b) 尽管存在解析错误,但我还是得到了我想要的结果数组。我应该忽略错误吗?

c) 在命令的开头添加#!/bin/bash 时(仍在shell 脚本之外,只是在命令行中)为什么无法访问结果? (输入echo ${msValuesArray[@]} 返回一个空数组。)

d) 在 shell 脚本中运行时,是否发生了同样的错误,只是没有打印到终端?

感谢任何帮助。谢谢。

【问题讨论】:

  • starts 数组是什么样的?它是否具有与startTimes 相同数量的元素?这是你的整个剧本吗?你如何运行它? “在命令行中添加#!/bin/bash”是什么意思?
  • 抱歉,复制/粘贴错误。我刚刚修好了。它应该是startTimes。我还没有完整的脚本,只是在命令行中一次测试一个命令,以确保我的脚本能够运行(如果有更好的方法,我会全力以赴)。对于shebang,如果我在命令行中输入所有这些#!/bin/bash; for...(etc)...; done,我不会得到任何解析错误——但也没有可访问的结果。我假设它在另一个我无法访问的 shell 中运行?显然还在学习。
  • 如果有帮助,startTimes 看起来像这样:0 87053 91463 190062 194472 290520 294930 387582 391992。只是一堆整数。

标签: bash shell bc herestring


【解决方案1】:

您可以直接遍历数组,而不是通过索引:

for t in "${startTimes[@]}"; do
    msValuesArray+=($(bc <<< "$t / 44.1"))
done

这使得循环更容易阅读。

您收到解析错误,因为您尝试访问不存在的元素(请参阅 John1024 的答案),因此 bc 只看到 / 44.1。你不应该忽略这个错误。

您应该引用您的此处字符串,即使在这种情况下它似乎不会导致问题1

如果你只是在命令行输入#!/bin/bash,它根本没有任何作用,它只是被认为是一个注释。它只作为脚本的第一行做一些事情,即指示应该使用什么解释器。如果如您的评论所示,您在一行中输入整个内容为

#!/bin/bash; for ... (etc) ...

什么都没有发生。这只是一个评论。

最后,您正在截断您的结果。如果您希望它们更精确,可以将scale 设置为合理的值,如

bc <<< "scale = 3; $t / 44.1"

1 (不需要的)分词和通配等问题。 This article 很好地概述了引用的方式和原因。

【讨论】:

  • 非常感谢!你能详细说明这里字符串引号的重要性吗?一般来说,我对报价的用法仍然很模糊。
  • @Urphänomen 我添加了一个关于引用的好文章的链接。经验法则实际上是“如有疑问,请引用”。
  • 太好了,谢谢@Benjamin W。概述正是我所需要的,非常感谢。
  • @Urphänomen Benjamin 的for t in "${startTimes[@]}" 解决方案在我看来是一个不错的解决方案。我建议你接受他的回答。
【解决方案2】:

你有一个非 1 问题。请注意,在您的示例 startTimes 中,seq 会生成 10 个数字:

$ startTimes=(0 87053 91463 190062 194472 290520 294930 387582 391992)
$ seq 0 ${#startTimes[@]}
0
1
2
3
4
5
6
7
8
9

问题是 startTimes 只有 9 个条目:

$ declare -p startTimes
declare -a startTimes=([0]="0" [1]="87053" [2]="91463" [3]="190062" [4]="194472" [5]="290520" [6]="294930" [7]="387582" [8]="391992")

i=9 时,startTimes[9] 的计算结果为空字符串,这会导致您看到bc 错误:

$ i=9; msValuesArray+=($(bc <<< ${startTimes[i]}/44.1))
(standard_in) 1: syntax error

或者,更直接地:

$ bc <<<"/44.1"
(standard_in) 1: syntax error

【讨论】:

  • 谢谢!很有帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 2015-03-31
  • 1970-01-01
相关资源
最近更新 更多