ugh.book

(singke) #1
“It Can’t Be a Bug, My Makefile Depends on It!” 189

Filename Expansion


There is one exception to Unix’s each-program-is-self-contained rule: file-
name expansion. Very often, one wants Unix utilities to operate on one or
more files. The Unix shells provide a shorthand for naming groups of files
that are expanded by the shell, producing a list of files that is passed to the
utility.


For example, say your directory contains the files A, B, and C. To remove
all of these files, you might type rm . The shell will expand “” to “A B
C” and pass these arguments to rm. There are many, many problems with
this approach, which we discussed in the previous chapter. You should
know, though, that using the shell to expand filenames is not an historical
accident: it was a carefully reasoned design decision. In “The Unix Pro-
gramming Environment” by Kernighan and Mashey (IEEE Computer,
April 1981), the authors claim that, “Incorporating this mechanism into the
shell is more efficient than duplicating it everywhere and ensures that it is
available to programs in a uniform way.”^3


Excuse me? The Standard I/O library (stdio in Unix-speak) is “available to
programs in a uniform way.” What would have been wrong with having
library functions to do filename expansion? Haven’t these guys heard of
linkable code libraries? Furthermore, the efficiency claim is completely
vacuous since they don't present any performance numbers to back it up.
They don’t even explain what they mean by “efficient.” Does having file-
name expansion in the shell produce the most efficient system for program-
mers to write small programs, or does it simply produce the most efficient
system imaginable for deleting the files of untutored novices?


Most of the time, having the shell expand file names doesn’t matter since
the outcome is the same as if the utility program did it. But like most things
in Unix, it sometimes bites. Hard.


Say you are a novice user with two files in a directory, A.m and B.m.
You’re used to MS-DOS and you want to rename the files to A.c and B.c.
Hmm. There’s no rename command, but there’s this mv command that
looks like it does the same thing. So you type mv .m .c. The shell
expands this to mv A.m B.m and mv overwrites B.m with A.m. This is a
bit of a shame since you had been working on B.m for the last couple of
hours and that was your only copy.


(^3) Note that this decision flies in the face of the other lauded Unix decision to let any
user run any shell. You can’t run any shell: you have to run a shell that performs
star-name expansion.—Eds.

Free download pdf