This document is a work in-progress, providing notes and comments on, as well as my solutions
to exercises found in,
The Unix Programming Environment[KP84]
by Brian W. Kernighan and Rob Pike. I've decided to restrict myself to notes on exercises and
examples. As the Preface states, This book should be read at a terminal, so that you can
experiment, verify or contradict what we say, explore the limits and the variations.
Exploring
any operating environment exposes many details, which I leave to other notes and reflections
related to particular systems, or books I've read (or in some cases written for Linux
administration and programming instruction, of which this book was always a key reference).
Most Unix systems of today fall into a few categories. There's the classic BSD systems like OpenBSD, NetBSD, FreeBSD, and DragonFly BSD. There's also the POSIX compliant, trademarked UNIX® systems, which include some GNU/Linux systems, HP-UX, Solaris, AIX, and macOS. There's also Unix clones such as Minix, or the many different GNU/Linux systems, including proprietary systems such as Red Hat Enterprise Linux, commercial systems like Ubuntu and SUSE, or custom distributions such as my own.
A reference to the Unix Programmer's Manual refers to two basic books: the man pages and the articles. For the purpose of this book, the Seventh Edition UNIX system from Bell Labs is what it means here. The Tenth Edition was the final research release. I understand that the Eighth Edition sources have been posted to the Unix Heritage Society website. System III and System V from the Unix Systems Laboratories was the commercial branch of Unix. For Linux, this basically means the man pages and explanatory white papers provided with the system, and perhaps the POSIX and LSB (ISO/IEC 23360-1:2006) standards.
RETURN in the book refers to the key that generates the carriage return control character. PC keyboards usually have Enter now, but it’s the same key. Also, the Backspace key means send the backspace character then send the delete character. As the book noted, sometimes the Delete key may do other things than delete a character.
Towards the end of section 1.1, Mistakes in typing describes shell behavior that is likely confusing to modern users. Being able to backspace and delete something previously typed was not available. Bill Joy distributed a tape called the Berkeley System Distribution (BSD) that included a visual editor (ex and vi) and the C Shell (CSH), which introduced the idea of being able to edit the command line and correct mistakes. The GNU Project's Bash, which is at the core of most Unix systems today (though older ones still use the Korn Shell replacement to Bourne's), defaults to Emacs mode. This provides not only command editing and correction, but command completion options, and history paging.
To get the old fashioned behavior in Bash, instead of using
@
character for line kill, use Ctrl-u.
To erase the previous character, type Ctrl-\? (hold
down both the Control/Ctrl key and
and the backslash key, then type the key with the question
mark (the Shift key is not necessary here). However,
to accomplish Exercise 1-1, these must be remapped to the
@
and #
characters, respectively.
Typing stty -a using the GNU Coreutils
stty
command will show the current settings. An
initial start is as follows:
$ stty erase \#Enter stty kill @Enter
Unfortunately, this does not honor the \
character
as an escape, so the example's \@
will still delete
the line. The following is what the exercise was expected to look
like:
$ date@
Notice that the trailing $
is not present, so
the book does not expect you to type the Enter key,
but instead expected the \@
part of your typing
to not print the \
part. As the book indicated,
typically this will still put you on a new line with a prompt.
If you got command not found
, then you pressed
Enter when typing date\@, which makes
sense: there's no date\@
command, only
date
, and the @
character is not
being interpretted as a line kill, nor is the \
escaping it.
For now, that's as far as I got. With some more persistence,
I'm sure I could identify why the \
character is
not escaping the control characters defined by the
stty
command, and also identify how to explain how
to set everything back the way it was easily. For now, you may
have to log out, then back in again, or use the
stty
command to configured the old behavior.
So with Bash on GNU/Linux and macOS, use Backspace
instead of #
(as the book suggests you test), and
Ctrl-u instead of @
.
Exercise 1-2 has four commands. The first types the
date
command with the expected output. The second
has a #
that has nothing to delete before running
the date
command. The third escapes the
#
which becomes a comment. The fourth escapes the
escape to a literal \
, which then escapes the
#
to a comment (instead of a backspace+delete),
and thus returns from Bash a command not found
.
This section may not make sense until it is realized that slow baud rate serial connections using dumb terminals and dial-up modems is assumed here. Unless dealing with network or internet latency, the X/ON and X/OFF behavior of the Break key, or Ctrl-q and Ctrl-s won't make sense.
Typically, the Delete key does not break out of
a write
session, only Ctrl-d. Only
my Microsoft Natural Keyboard appears to still have a
Pause or break key, but it does not
break out of a write
session either.
Unix and Plan 9 printed the entire manual to the screen
(all available sections, instead of only the first). Part of
this is because of the default behavior of the man
and man-db
packages, as originated from BSD, of
using the more
pager (and on GNU/Linux, the
less
pager) by default. Some systems even have
plain text (cat
) directories (e.g.
/usr/man/cat1/
instead of
/usr/man/man1/
) where the man page can be
printed with cat
or searched directly with the
grep
command. Scrolling the screen on Linux can
be done by holding down the Shift key, and pressing
PgUp or PgDown. Within a graphical
windowing environment, the screen can be scrolled with a
mouse, and some graphical terminal emulators can be configured
with infinite scroll back (otherwise typically restricted).
To quit a manual type q. Use the space bar or Enter to move forward in a manual, or b or Ctrl-b to move back. Search with the / character.
The learn
command is typically not found on Linux systems. Professor
Kernighan (the author) has a copy from research Unix at his Princeton
mirror.
Research Unix home directories were in /usr/
(for user). Most Linux systems use /home/
, and
even have a /root/
(restricted) home directory.
This can be confusing keeping the root (/
) and
root home (/root/
) directory distinct in your
mind. The administrative user is ID number 0, called
root (instead of something like adm
)
because it is the user without a home directory that defaults
to the root directory, (at least in research Unix).
Most Unix systems have removed the .
from the
path, meaning commands in the current working directory won't
execute by default. This is to avoid trojan attacks.
On occasion, files like .profile
are mentioned
as being in your home directory. A file that starts with a dot
is treated as a hidden file by some programs, and depending
on configuration the shell. For instance, ls *
in
the book is shown to print the dot files, but not with Bash on
GNU/Linux systems or macOS. This makes things trickier to
handle those hidden files. The Unix researchers later decided
that it is probably best to not treat the files as hidden after
all, but so many programs store their configurations in these
dot files, instead of say $HOME/etc/
, that using
your home directory for files in general is likely not a good
idea if those files aren't treated as hidden.
The explanation in a foot note regarding
.profile
seem to assume that it is read with
every shell, and thus every command, invocation. I don't know
when (if?) this changed, but shells like the Korn shell, Bash,
CSH, and ZSH all have a run commands file (e.g.
.bashrc
) that does this, and the
$HOME/.profile
and /etc/profile
are only read at login (unless explicitly invoked, e.g.
su -
).
The PS1
example in my edition of UPE was
missing the closing apostrophe-quote. I also noticed in the
-t
explanation at the top of page 14 that it
describes it as "recent use", but the ls
command defaults
to printing the modification time not the access time.
This describes the file system and directory structure of Unix. In a way, GNU/Linux systems are
quite similar, but macOS in particular has made a break from the classic research Unix directory
structure, (with the exception of POSIX requirements like /dev/null
, and Homebrew
which is actually a third-party tool). The book is written in terms of Unix editions 7 and 8. It's
necessary to understand the research Unix layout to identify the equivalent for GNU/Linux or
existing Unix systems.
I've used the overwrite
script, from section 5.5. As some problems arose with its
use (this really is a great tool), I made some modifications to fix those problems. See
/dee/software/rmcr/overwrite.txt.
©2019-2021, 2023 David Egan Evans.