184 Programming SH(1) Unix Programmer's Manual SH(1) NAME sh, for, case, if, while, :, ., break, continue, cd, eval, exec, exit, export, login, read, readonly, set, shift, times, trap, umask, wait - command language SYNOPSIS sh [ -ceiknrstuvx ] [ arg ] ... DESCRIPTION Sh is a command programming language that executes commands read from a terminal or a file. See invocation for the meaning of arguments to the shell. [...] BUGS If is used to provide standard input to an asynchronous process invoked by &, the shell gets mixed up about naming the input document. A garbage file /tmp/sh* is created, and the shell complains about not being able to find the file by another name. We spent several minutes trying to understand this BUGS section, but we couldn’t even figure out what the hell they were talking about. One Unix expert we showed this to remarked, “As I stared at it and scratched my head, it occurred to me that in the time it must have taken to track down the bug and write the BUGS entry, the programmer could have fixed the damn bug.” Unfortunately, fixing a bug isn’t enough because they keep coming back every time there is a new release of the OS. Way back in the early 1980s, before each of the bugs in Unix had such a large cult following, a programmer at BBN actually fixed the bug in Berkeley’s make that requires starting rule lines with tab characters instead of any whitespace. It wasn’t a hard fix—just a few lines of code. Like any group of responsible citizens, the hackers at BBN sent the patch back to Berkeley so the fix could be incorporated into the master Unix sources. A year later, Berkeley released a new version of Unix with the make bug still there. The BBN hackers fixed the bug a second time, and once again sent the patch back to Berkeley.
Programming in Plato’s Cave 185 …The third time that Berkeley released a version of make with the same bug present, the hackers at BBN gave up. Instead of fixing the bug in Ber- keley make, they went through all of their Makefiles, found the lines that began with spaces, and turned the spaces into tabs. After all, BBN was pay- ing them to write new programs, not to fix the same old bugs over and over again. (According to legend, Stu Feldman didn’t fix make’s syntax, after he real- ized that the syntax was broken, because he already had 10 users.) The Source Is the Documentation. Oh, Great! If it was hard to write, it should be hard to understand. —A Unix programmer Back in the documentation chapter, we said that Unix programmers believe that the operating system’s source code is the ultimate documentation. “After all,” says one noted Unix historian, “the source is the documentation that the operating system itself looks to when it tries to figure out what to do next.” But trying to understand Unix by reading its source code is like trying to drive Ken Thompson’s proverbial Unix car (the one with a single “?” on its dashboard) cross country. The Unix kernel sources (in particular, the Berkeley Network Tape 2 sources available from ftp.uu.net) are mostly uncommented, do not skip any lines between “paragraphs” of code, use plenty of goto’s, and gener- ally try very hard to be unfriendly to people trying to understand them. As one hacker put it, “Reading the Unix kernel source is like walking down a dark alley. I suddenly stop and think ‘Oh no, I’m about to be mugged.’ ” Of course, the kernel sources have their own version of the warning light. Sprinkled throughout are little comments that look like this: /* XXX */ These mean that something is wrong. You should be able to figure out exactly what it is that’s wrong in each case.