The Shell Game 153 It says, “If there is at least one argument ( ${1+ ), then substitute in all the arguments ( “$@” ) preserving all the spaces, etc. within each argument. If we used only “$@” then that would substitute to “” (a null argu- ment) if there were no invocation arguments, but we want no argu- ments reproduced in that case, not “”. Why not “$*” etc.? From a sh(1) man page: Inside a pair of double quote marks (“”), parameter and command substitution occurs and the shell quotes the results to avoid blank interpretation and file name generation. If $* is within a pair of double quotes, the positional parameters are substituted and quoted, separated by quoted spaces (“$1 $2 …”) however, if $@ is within a pair of double quotes, the positional parameters are substituted and quoted, separated by unquoted spaces (“$1” “$2” …). I think ${1+“$@”} is portable all the way back to “Version 7 Unix.” Wow! All the way back to Version 7. The Shell Command “chdir” Doesn’t Bugs and apparent quirky behavior are the result of Unix’s long evolution by numerous authors, all trying to take the operating system in a different direction, none of them stopping to consider their effects upon one another. Date: Mon, 7 May 90 22:58:58 EDT From: Alan Bawden alan@ai.mit.edu Subject: cd . . : I am not making this up To: UNIX-HATERS What could be more straightforward than the “cd” command? Let's consider a simple case: “cd ftp.” If my current directory, /home/ar/alan, has a subdirectory named “ftp,” then that becomes my new current directory. So now I’m in /home/ar/alan/ftp. Easy. Now, you all know about “.” and “. .”? Every directory always has two entries in it: one named “.” that refers to the directory itself, and one named “. .” that refers to the parent of the directory. So in our example, I can return to /home/ar/alan by typing “cd . .”.
154 csh, pipes, and find Now suppose that “ftp” was a symbolic link (bear with me just a while longer). Suppose that it points to the directory /com/ftp/pub/ alan. Then after “cd ftp” I’m sitting in /com/ftp/pub/alan. Like all directories /com/ftp/pub/alan contains an entry named “. .” that refers to its superior: /com/ftp/pub. Suppose I want to go there next. I type: % cd .. Guess what? I’m back in /home/ar/alan! Somewhere in the shell (apparently we all use something called “tcsh” here at the AI Lab) somebody remembers that a link was chased to get me into /com/ftp/ pub/alan, and the cd command guesses that I would rather go back to the directory that contained the link. If I really wanted to visit /com/ ftp/pub, I should have typed “cd . / . .”. Shell Programming Shell programmers and the dinosaur cloners of Jurassic Park have much in common. They don’t have all the pieces they need, so they fill in the miss- ing pieces with random genomic material. Despite tremendous self-confi- dence and ability, they can’t always control their creations. Shell programs, goes the theory, have a big advantage over programs writ- ten in languages like C: shell programs are portable. That is, a program written in the shell “programming language” can run on many different fla- vors of Unix running on top of many different computer architectures, because the shell interprets its programs, rather than compiling them into machine code. What’s more, sh, the standard Unix shell, has been a central part of Unix since 1977 and, thus, we are likely to find it on any machine. Let’s put the theory to the test by writing a shell script to print the name and type of every file in the current directory using the file program: Date: Fri, 24 Apr 92 14:45:48 EDT From: Stephen Gildea gildea@expo.lcs.mit.edu Subject: Simple Shell Programming To: UNIX-HATERS