musasabi musasabi - 14 days ago 8
Linux Question

How to add values to bash arrays?

Sorry for the subject clone, but given that the technique I used successfully from that answer doesn't work as expected on a new script, I figured it was time for a new question.

Anyway, the following script is fairly straight forward:

missed_symbols=()

grep missed ${dest}/scribe.log | while read -r line; do
symbol=$(echo "${line}" | cut -d' ' -f1)
missed_symbols+=("$symbol")
done

grep missed ${dest}/scribe_close.log | while read -r line; do
symbol=$(echo "${line}" | cut -d' ' -f1)
missed_symbols+=("$symbol")
done

for symbol in "${missed_symbols[@]}"; do
echo "Scribe missed a turn in ${symbol}"
done
echo "Scribe missed ${#missed_symbols[@]} turns today"
exit 0


And adding
-x
to the
#!/bin/bash
line tells me that, indeed, it is assigning the first word of each
$line
from
$missed_symbols[@]
to
$symbol
. Yet, when I check
${#missed_symbols[@]}
, I get zero. And, of course, looping through it produces no output.

So, where's my typo?

Answer

Pipelines create subshells. Changes to shell variables made in subshells disappear when those subshells exit.

Thus, instead of piping into a while read loop, redirect from a process substitution:

while read -r line; do
  symbol=${line%%" "*}
  missed_symbols+=("$symbol")
done < <(grep missed ${dest}/scribe.log)