Strange behavior with readarray (aka mapfile)

$ readarray list <<< "a b c d e f g"
$ echo ${list[@]}
a b c d e f g

$ echo "a b c d e f g" | readarray list2
$ echo ${list2[@]}
a blank line

I read a post the same thing happens with cat vs < on another forum but the poster did not know why.

Any ideas?

Mike

When you have a pipeline, the standards allow (but do not require) the elements of the pipeline to be in different shell execution environments. If your system does put them in different shell execution environments, the readarray may be setting list2 in one shell execution environment, but not in the environment where the second echo is running. If that is your problem, the following should work:

echo "a b c d e f g" | ( readarray list2
echo ${list2[@]} )

I'm running on OS/X, which does not have a readarray command. So, I can't test it, but hopefully this will give you some hints that may help.

4 Likes

Don Cragun is right - in e.g. bash, pipes are executed in subshells, and it is difficult to get the results back to the parent shell for further processing. His proposal prints the array, yes, but that's it, it's lost for the original shell.
If you need to process the array, you can (in bash!)

  • put further processing steps into the subshell as well
  • use process substitution: $ readarray list < <(echo "a b c d e f g")
  • use array assignment and command substitution: $ list=( $(echo "a b c d e f g") )
  • just array assignment: $ list=( "a b c d e f g" )
1 Like

Thanks to both of you for the explanation and your suggestions.

Mike