dragonxlwang
dragonxlwang

Reputation: 482

Bash word splitting mechanism

I am new to Bash and I am seeing that there is automatic word splitting done by Bash:

a="1  2     3 4"

If I echo "a" by echo $a I got 1 2 3 4, which has done word splitting implicitly. If I loop through "a", I got 1, 2, 3, and 4 respectively.

I also read from here that

The shell scans the results of parameter expansion, command substitution, and arithmetic expansion that did not occur within double quotes for word splitting.

And I also found that if I have

b=$a;
echo "$b"

I would get

"1 2 3 4"

So, here is my problem: when is the word splitting done? does it change the string itself? Does it only take effect when I use echo or for (loop)?

More generally, how does bash handle it?

Upvotes: 3

Views: 4836

Answers (3)

clt60
clt60

Reputation: 63952

Bash works as next - when parsing a script or command line:

  1. parsing and lexical analysis
  2. expansion
    1. brace expansion
    2. tidle expansion
    3. variable expansion
    4. artithmetic and other substitutions
    5. command substitution
    6. word splitting
    7. filename generation (globbing)
  3. removing quotes

as you can see, the word splitting is nearly at the end, so after the e.g. arithmetic exansion but before the filename globbing, Removing the quotes is the last step.

Upvotes: 4

chepner
chepner

Reputation: 531858

There are actually several rounds of word-splitting. The first is performed prior to parsing the command line, so echo $a is split into two words echo and $a. (This is why something like a="echo foo | wc -l"; $a doesn't execute a pipeline; parsing is complete before $a is expanded). After that round of word-splitting is over, parameter expansion occurs to produce 2 strings, echo and 1 2 3 4. The string resulting from parameter expansion then undergoes word-splitting itself, since it is not quoted, producing 4 additional words 1, 2, 3, and 4.

In a for loop, the items in the list are subject to word-splitting:

for b in $a; do

is expanded (after word-splitting produces for, b, in, $a, ;, and do) to for, b, in, 1 2 3 4, ;, and do. Again the string resulting from parameter expansion undergoes word-splitting to 1, 2, 3, and 4.

Upvotes: 7

choroba
choroba

Reputation: 241988

Read man bash. For assignment, it says

All values undergo tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal [ ... ] Word splitting is not performed, with the exception of "$@" as explained below under Special Parameters. Pathname expansion is not performed.

Word splitting also does not happen in [[ ]] conditions:

Word splitting and pathname expansion are not performed on the words between the [[ and ]]

Upvotes: 2

Related Questions