Here's another example in which command-line parsing is important. Consider this shell alias for counting the number of words in all files:
wc
Section 16.6
%alias words "wc -w *"
csh, tcsh $alias words="wc -w *"
ksh, bash
Right away, we can see one
effect of command-line parsing. The shell sees the quotation marks and knows not
to expand wildcards inside them. Therefore, words
is aliased to wc -w *
;
the *
isn't evaluated when you create the
alias. (If wildcards were processed before quotes, this wouldn't work.)
Now, think about what happens when you execute the alias. You type:
% words
The shell starts working through its steps and eventually performs alias substitution. When this happens, it converts your command into:
wc -w *
Now, watch carefully. The shell continues working through the process of
interpretation (redirection, variable substitution, command substitution) and
eventually gets to filename expansion. At this point, the shell sees the
*
on the command line, expands it, and
substitutes the files in the current directory. Seems simple enough. But think:
you didn't type this *
; the shell put it
there when it expanded the wildcard. What would have happened if the shell
expanded wildcards before substituting aliases? The *
would never have been expanded; by the time the shell put it on
the command line, the wildcard expansion stage would be over, and you'd just
count the words in a file named *
(which
probably doesn't exist).
To me, the amazing thing is that all this works — and works well! The workings of the command line are intricate and complex, but the shell almost always does what you want — and without a lot of thought.
— ML