Bash bc 返回 (standard_in) 1 : parse error only when part of for loop

标签 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 脚本中运行时,是否发生了同样的错误但只是没有打印到终端?

感谢任何帮助。谢谢。

最佳答案

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

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很好地概述了引用的方式和原因。

关于Bash bc 返回 (standard_in) 1 : parse error only when part of for loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45927317/

相关文章:

bash - 重命名文件但将它们保留在当前的子目录中

linux - unix - 打印文件中不同的控制字符列表

bash - 用于检查字符串是否存在于以逗号分隔的字符串列表中的 Bash 脚本

shell - 使用shell脚本生成一个随机文件

python - 从 Python 运行 bash 脚本但出现 Windows 错误 193

python - 如何使用 Python 将输入发送到 bc 并从 bc 获取输出?

bash - `printf "2+2 "| bc` 返回语法错误,`echo "2+2 "| bc` 有效,它们如何以不同的方式处理字符串?

bash - 从命令行在目录中查找文件

bash - 如何使用脚本 cd 进入目录?

linux - 在 awk 的 BASH shell 中使用 bc 作为守护进程