December 25, 2009

Day 25 - Introducing UNIX 4.0!

I know. Advent is only 24 days. Continuing from last year's "Jordan had no idea advent was only 24 days" tradition, here is a bonus 25th article to wrap up this year's sysadvent. Enjoy! :)

I have these two nearly-30-year old computer manuals that were given to me by a coworker who thought I'd be interested. Boy was I! I'm that kind of nerd. Anyway, these books were internal Bell Labs manuals/guides for helping folks do stuff on UNIX. They were printed before I was born and contain great content for interviews because they document UNIX shell, editor, system programming, and other pieces that are still here, today. You'll find few of the topics covered have changed since UNIX, 30 years ago; FreeBSD, Linux, and Solaris all have fairly clear heritage here.

Welcome to UNIX Release 4.0!

The books themselves contain multiple sections covering a range of topics. With respect to the UNIX version covered, the intro says it is relevant to UNIX 4 (1974), but I think most of it is relevant UNIX version 7 (1979) which was released nearer to the print dates in these books.

The intro to the book, which discusses notation and conventions, explains this:

Entries in Section n of the UNIX User's Manual are referred to by name(n).
I always did think that the name(n) notation for manpages was useful, and now I have a better understanding of how old this stuff really is.

One of these books is "UNIX Programming Starter Package." It includes "UNIX Shell Tutorial" by G. A. Snyder and J. R. Mashey. The copy I have is dated January 1981. It starts with talking about the filesystem. "If a path name begins with a /, the search for the file begins at the root of the entire tree; otherwise, it begins at the user's current directory." It goes on to discuss absolute vs relative path nomenclature.

Next, it discusses processes: how a fork of will spawn an identical copy of the original process, that both can continue to execute in parallel, and that either may call exec(2) to abandon the current program and start a new one. It also talks about wait(2) and how the parent might use it, and includes a diagram of it:

Continuing the process discussion, this tutorial explains that child processes inherit open files and signals. You'll learn about process termination, including the 8-bit exit status value and about success (zero) and failure (non-zero). Signals are also explained: a signal may come from "another process, from the terminal, or by UNIX itself." Signals can be ignored or caught by programs and the book makes special highlight of the interrupt signal, which can come from a user pressing the right key sequence. The tutorial explains 3 ways the signals are generally handled in a shell: the active program might die due to interrupt, the shell itself ignores the interrupt signal, and tools like ed(1) catches the signal and uses it to abort the current action (like printing) without exiting.

In case you were really wondering about the origins of the SIGHUP signal, this book's "UNIX for Beginners" chapter explains that "hanging up the phone will stop most programs."

Also covered are position parameters ($1, $2, ...), variables such as PATH, HOME, and PS1 (your shell prompt), "Command substitution" aka `stuff in backticks`, special variables like $#, $?, $$, and more. Keyword paramters also are documented here and how they relate to the environment (things like "FOO=hello ./mycommand arg1..." where FOO is an environment variable passed to ./mycommand.

Pipes, input redirection, process backgrounding, nohup, etc. All talked about here.It also has a pile of sample scripts, including this one called "null" which is a 1980's UNIX version of the modern touch(1) command:

#       usage: null file
#       create each of the named files as an empty file
for eachfile
do
        > $eachfile
done
When we run this on Ubuntu 9.04 in /bin/sh, it still works.
% sh null.sh a b c d e
% ls
a  b  c  d  e  null.sh*

Basically, The unix shell (linux, freebsd, etc, too) hasn't changed much in 30 years. The concepts, implementations, and syntax are, for the most part, exactly the same. Some important quotes from this tutorial from a section titled "Effective and Efficient Shell Programming:"

"In the author's opinion, the primary reason for choosing the shell procedure as the implementation method is to achieve a desired result at a minimum human cost."
"One should not worry about optimizing shell procedures unless they are intolerably slow or are known to consume a lot of resources."
"Emphasis should always be placed on simplicity, clarity, and readability."
Other sections in the "UNIX Programming Starter Package" includes a C reference and UNIX system reference, which details important concepts such as "everything is a file descriptor" among the general programming library reference.

I skipped the first section in this book, which contains a very excellent introduction to ed(1), which, as you should guess by now, is still totally valid documentation today. If you've never used ed(1), learning about it shows distinct ancestry to ex(1) and it's successor, vi(1).

The second Bell Labs UNIX manual I have is "UNIX Text Editing & Phototypesetting Starter Package." That's quite a mouthful of title! It goes extensively into how to use ed(1) and other tools that would help you edit stuff. Past that, it dives head first into troff/nroff, mm, tbl (table formatting), and eqn (math formulas). Reflecting on the general syntax of troff/nroff, and comparing that with HTML, Markdown, whatever random wiki markups are floating about, etc, I don't really feel like we've made progress much progress since troff.

In case you weren't aware, all your manpages are written in modern nroff.

% gzip -dc /usr/share/man/man1/sh.1.gz | less
< I skipped the copyright stuff >
.Dd January 19, 2003
.Os
.Dt SH 1
.Sh NAME
.Nm sh
.Nd command interpreter (shell)
.Sh SYNOPSIS
.Nm
.Bk -words
.Op Fl aCefnuvxIimqVEb
.Op Cm +aCefnuvxIimqVEb
So, besides a fun history lesson, what are the take aways? Personally, I use some of this material for interview questions. Pillars of UNIX that are still valid today are quite meaningful and useful to know, and I just might expect you to understand them if the position demands it.

I have a few photos of the books and content on Flickr.

Further reading:

2 comments :

Howie said...

null.sh is nothing like the *intended* use of touch(1). touch(1) is intended to alter the file times of source files, so that make(1) sees them as new (or touched) and rebuild appropriately. The fact it creates null files where they don't exist is more of a useful side-effect I think.

According to the FreeBSD manpage, touch first appeared in UNIX 7, so it was already around when your manuals were printed.

I thought the v7 manpages were online, but I can only find v8:

http://man.cat-v.org/unix_8th/1/touch

I started using unix as big iron was dying and workstations (but not yet linux) were the future, but there's something very cool about being able to trace the lineage of all these things back so far :-)

Check out UNIX v1 manuals from the same site: http://man.cat-v.org/unix-1st/

Gini said...

I am the G. A. Snyder of Snyder & Mashey who co-authored the "UNIX Shell Tutorial". I would love to have a copy of that work, as I have lost track of mine. Any chance you could scan and email it to me?