I understand command substitution. I understand subshells. I do not understand why using a subshell changes the structure of my array.
Given this command output: (use of openstack command is not intended to be relevant)
bash$ floating ip list -c 'Floating IP Address' -f value
172.25.250.106
172.25.250.107
172.25.250.101
Attempt to capture in an array, but all addresses end up in element 0:
bash$ float=$( openstack floating ip list -c 'Floating IP Address' -f value )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
1
bash$ echo ${float[0]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[0]}
44
The whole output was captured as a string and not parsed into elements. I was expecting each word to become an element. When I repeat this to ensure that each IP address is quoted (using -f csv instead of -f value), the results are the same.
Next, I put the command substitution in a subshell:
bash$ unset float
bash$ float=( $( openstack floating ip list -c 'Floating IP Address' -f value ) )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
3
echo ${float[0]}
172.25.250.106
echo ${#float[0]}
14
This was the behavior I expected originally. I also notice that building the array using a read statement worked as expected:
bash$ unset float
bash$ read -a float <<< $( openstack floating ip list -c 'Floating IP Address' -f value )
bash$ echo ${float[@]}
172.25.250.106 172.25.250.107 172.25.250.101
bash$ echo ${#float[@]}
3
echo ${float[0]}
172.25.250.106
echo ${#float[0]}
14
I would like to see the original command substitution work. Wondering if I should have set a field separator first or what else I am missing. I am trying to understand what causes the difference in behavior.
float=$( ...)
is command substitution, not an array at all.