Search code examples
bashquoting

Why can `for in` not split string directly in bash?


For example:

# case 1
for i in "a b c"; do echo -n $i| od -b; done
# case 2
v="a b c"; for i in $v; do echo -n $i| od -b; done

Output:

0000000 141 040 142 040 143
0000005
0000000 141
0000001
0000000 142
0000001
0000000 143
0000001

Why can for in not split string directly in bash? What is the difference between case 1 and case 2?


Solution

  • Word splitting is a feature in unquoted parameter expansion (as well as unquoted command expansion). It's not a feature of for loops.

    • Unquoted variables split strings in for loops because unquoted variables split strings (almost) everywhere.

    • for loops don't split strings directly because they don't split strings at all. It's not the loop's responsibility.

    Here's three examples, each with a literal string, a quoted variable and an unquoted variable. You can see that there are no special cases, all splitting is due to unquoted parameter expansion:

    var="a b c"
    
    command "a b c" "$var" $var
                            ^-- Only thing that splits
    
    array=("a b c" "$var" $var)
                            ^-- Only thing that splits
    
    for s in "a b c" "$var" $var
    do ...                  ^-- Only thing that splits