Important parts of Unix's history happened before readline support was common

August 17, 2020

Unix and things that run on Unix have been around for a long time now. In particular, GNU Readline was first released in 1989 (as was Bash), which is long enough ago for it (or lookalikes) to become pretty much pervasive, especially in Unix shells. Today it's easy to think of readline support as something that's always been there. But of course this isn't the case. Unix in its modern form dates from V7 in 1979 and 4.2 BSD in 1983, so a lot of Unix was developed before readline and was to some degree shaped by the lack of it.

(This isn't to say that GNU Readline and Bash were the first sources of readline style editing, command completion, and so on; on Unix they go back at least as far as 1983, with tcsh. But tcsh wasn't pervasive for various reasons.)

One obvious thing that was shaped by the lack of readline was csh. Csh has a sophisticated set of operations on your command history that are involved through special strings embedded in your command line. To quote the 4.2 BSD csh manpage:

History substitutions place words from previous command input as portions of new commands, making it easy to repeat commands, repeat arguments of a previous command in the current command, or fix spelling mistakes in the previous command with little typing and a high degree of confidence. History substitutions begin with the character `!' and may begin anywhere in the input stream (with the proviso that they do not nest).

The most well known history substitution for tcsh users is probably '!!', which repeats the previous command. Bash has a similar facility, cf, and even today the Bash manual calls out its similarity to csh's version. These days I suspect most people using Bash don't use Bash's history substitutions and just stick to readline stuff; it's generally more fluid and easy to deal with.

(This is an obvious observation, but at times it's easy to blur the old days of Unix together and lose track of how comparatively old some parts of it are. Or at least it is for me.)

PS: My impression is that the widespread availability of command and filename completion subtly shapes the kind of command names and file names that people use. When you don't have completion, it makes a lot of sense for names to be short and it doesn't matter if they're all jumbled together so that completion can't tell them apart. Famously, Unix loves short command names because they're short to type, which makes a lot of sense in a V7 environment.

Comments on this page:

From at 2020-08-17 00:58:10:

Huh, I didn't know the 't' in tcsh stands for "TENEX line editing". (For some reason I had thought it was csh that was advertised as the "line editing" shell...) I haven't ever had the chance to use TENEX but it seems to be rather influential in that regard – I remember seeing it mentioned in Kermit docs for the same reason.

History substitutions interact very poorly with bash's quoting/escaping mechanisms, to the point that I disable the function entirely so I could use ! in commands without fear. Haven't really missed it much; most of my needs are indeed served by readline (e.g. the Alt+. shortcut instead of !$). Admittedly there are some situations where ^foo^bar would be much faster than Ctrl-arrowing all the way back, but if the command gets so long then usually it's time to turn it into a shell script instead...

About the only time I use the ! stuff is to repeat a command in $().

Usually it's when I've run 'find' or 'grep -l' to get a list of files, and the next step is to go through them with an editor. I like to run the find/grep on its own first to see if the filenames look right, but then I can just do:

   vim $(!!)
Written on 17 August 2020.
« "It works on my laptop" is a blame game
Firefox and web browsers for Linux »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Mon Aug 17 00:08:46 2020
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.