BASH BC返回(标准_IN)1:仅在循环的一部分时解析错误



我正在通过整数${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循环也有效,但输出解析错误(外壳脚本之外)?

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

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

d)在外壳脚本内运行时,是否发生了相同的错误,但只是不打印到终端?

任何帮助将不胜感激。谢谢。

您可以直接在数组上迭代而不是通过索引:

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 诸如(不需要的)单词分裂和球形等问题。本文是关于引用的方式和原因的一个很好的概述。

您有一个偏外问题。观察,在您的示例开始时,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

最新更新