Bash bc返回(standard_in)1:仅在for循环的一部分时解析错误

时间:2017-08-28 21:02:02

标签: bash shell bc herestring

我遍历整数数组${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脚本中运行时,是否发生了相同的错误,但只是没有打印到终端?

感谢任何帮助。感谢。

2 个答案:

答案 0 :(得分:3)

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

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

这使循环更容易阅读。

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

你应引用你的here-string,即使在这个例子中它似乎没有引起问题 1

如果只在命令行输入#!/bin/bash,它根本没有效果,它只是一个评论。它只作为脚本的第一行,即指示应该使用什么解释器。如果你的评论所指出,你将整个事情输入一行

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

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

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

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

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

答案 1 :(得分:3)

你有一个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