I'm iterating through an array of integers ${startTimes}
(marker locations in an audio file, in samples) and using bc
to convert those integers to milliseconds. I'm passing the results into a new array ${msValuesArray}
. If I run each array element one at a time it works fine. If I run it in a for
loop:
for i in $(seq 0 ${#startTimes[@]}); do
msValuesArray+=($(bc <<< ${startTimes[i]}/44.1))
done
The resulting ${msValuesArray}
contains the expected results, but the terminal outputs (standard_in) 1: parse error
.
While I intend to use this in a shell script, and after reading other questions here I learned that adding #!/bin/bash
to the beginning of the command avoids the parse error, I still don't understand the following:
a) why does the manual passing of a ${startTimes}
element into bc
work without the parse error while the for
loop also works, yet outputs the parse error (outside of the shell script)?
b) despite the parse error, I have the resulting array that I want. Should I ignore the error?
c) when adding #!/bin/bash
to the beginning of the commands (still outside of the shell script, just in the command line) why are the results inaccessible? (Entering echo ${msValuesArray[@]}
returns an empty array.)
d) While running inside the shell script, is the same error happening but just not printing to the terminal?
Any help is appreciated. Thanks.
You can iterate over the array directly instead of going via indices:
for t in "${startTimes[@]}"; do
msValuesArray+=($(bc <<< "$t / 44.1"))
done
This makes the loop easier to read.
You get a parse error because you're trying to access a non-existing element (see John1024's answer), so bc
sees just / 44.1
. You shouldn't ignore the error.
You should quote your here-string, even though in this very instance it doesn't seem to cause problems1.
If you enter #!/bin/bash
just on the command line, it has no effect at all, it's just considered a comment. It only does something as the first line of a script, namely indicate what interpreter should be used. If, as indicated by your comment, you enter the whole thing on a single line as
#!/bin/bash; for ... (etc) ...
nothing at all happens. It's just a comment.
Lastly, you're truncating your results. If you want them more precise, you can set scale
to a sensible value, as in
bc <<< "scale = 3; $t / 44.1"
1 Problems such as (unwanted) word splitting and globbing. This article is a good overview about the how and why of quoting.