Reputation: 1328
Is this a correct way to read multi line input into an array in bash?
arr=( $(cat) );
echo "{arr[@]}"
I put this line into a script and I tried to read multiple input by hitting return key after each line but the script keeps on taking the input and does not print the elements of the array by coming to the second line, when I press ctrl C at the input console the script terminates. Please suggest if that the correct way to read multi line input from the command line?
Upvotes: 5
Views: 4270
Reputation: 46813
Several points to address:
First, don't use Ctrl-C but Ctrl-D to end the input: Ctrl-C will break the script (it sends the SIGINT signal), whereas Ctrl-D is EOF (end of transmission).
To print the array, one field per line, use
printf '%s\n' "${arr[@]}"
Now, the bad way:
arr=( $(cat) )
printf '%s\n' "${arr[@]}"
This is bad since it's subject to word splitting and pathname expansion: try to enter hello word
or *
and you'll see bad things happen.
To achieve what you want: with Bash≥4 you can use mapfile
as follows:
mapfile -t arr
printf '%s\n' "${arr[@]}"
or, with legacy Bash, you can use a loop:
arr=()
while IFS= read -r l; do
arr+=( "$l" )
done
printf '%s\n' "${arr[@]}"
If you want to print each line as it's typed, it's probably easier to use the loop version:
arr=()
while IFS= read -r l; do
printf '%s\n' "$l"
arr+=( "$l" )
done
If you're feeling adventurous, you can use mapfile
's callback like so:
cb() { printf '%s\n' "$2"; }
mapfile -t -c1 -C cb arr
Upvotes: 8