Iterating Bash arrays with spaces
The problem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #!/bin/sh $ a=(hello world foo bar) $ for i in #{a[*]}; do echo $i; done # Expected output: # hello # world # foo # bar # so far so good: # hello # world # foo # bar $ a=("hello world" "foo bar") $ for i in #{a[*]}; do echo $i; done # Expected output: # hello world # foo bar # omg: # hello # world # foo # bar |
The problem is caused by the affect that Bash uses space as array element separator internally.
Failed attempt
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/sh $ a=("hello world" "foo bar") $ for i in "#{a[*]}"; do echo $i; done # Expected output: # hello world # foo bar # zomg! # hello world foo bar |
The solution
The solution lies in the magical $@ expansion. When the $@ expansion is put in a quote, the shell automatically expands each element properly quoted:
1 2 3 4 5 6 7 8 9 10 11 12 | #!/bin/sh a=("hello world" "foo bar") for i in "#{a[@]}"; do echo $i; done # Expected output: # hello world # foo bar # yay! # hello world # foo bar |