Know-it-all In A Shell

Have you ever had the misfortune of spending some time in the company of a know-it-all?If so, you'll probably hate the feature of the tcsh we're discussing this month.The tcshhas a built in spell-correct feature used for fixing what has been typed at the commandline. It's rather like holding a conversation with a know-it-all. The bad thing is thatsometimes the tcsh is right. For example, if you were to type:

srot file

the shell responds with:

CORRECT>sort file (y|n|e|a)?

In this case the shell was right -- the command sort was misspelled. The reply choicesare as follows: y means accept the correction and run the proposed command; n means refusethe correction and run the command as typed; e means to drop into the command lineeditor so you can correct the command; and a means abort the command.


So far this seems like a good feature. The problems only arise when a know-it-all iswrong. For example, if you type:

sort names > names1

in a directory where only the file names exists, tcsh will think you mistyped thesecond argument (it always thinks that arguments are existing files) and will respondwith:

CORRECT>sort names > names (y|n|e|a)?

which is certainly NOT what you want.

Doing this would cause the file names to be destroyed because you cannot re-directoutput into the same file you're reading from. So in this case, the spell correct featurewas wrong. The command was correct as typed: You want the sorted contents of names to besaved in a new file called names1.

For these reasons, many people do not like the spell correct feature of the tcsh.Luckily, the authors of tcsh took this into account. Spell correct is turned off bydefault. To enable it, the variable named correct must be set to cmd or all:

set correct=cmd

If it's set as shown above, only commands and not arguments will be checked.


Most C shell users are aware that the variable prompt can be used to customize theshell prompt. The tcsh allows for several special strings in the prompt variable. Like thecsh, tcsh allows for the \! sequence which inserts the current command number. In thetcsh, this can also be written as %h which does not need the backslash escape. Where itdiffers from the csh is in the following characters:

%t current time
%B bold
%S inverse video
%~% current directory
%M full hostname
%% print a %

There are many more listed in the man page, but these are the most commonly used.Here's an example of a rather obnoxious but informative tcsh prompt setting:

set prompt='{%h}%B%t %M %b%~%%% '

which might result in a prompt something like:

{34}08:36 /disc/users/fredm%

where the time would keep changing and both the time and the hostname would be in boldtext. Note that the %b in the prompt string turns off the bold font.

The tcsh has many variables unknown to the csh. Some are used to control functionsunique to the tcsh, like correct. There are also many variables automatically set by thetcsh, some of which can be quite useful when writing startup files. For example, thevariable HOST is set to the name of the host and the variable HOSTTYPE is set to machinetype, using a pre-defined symbolic name like hp9000s800. There are many more newvariables listed in the tcsh man page.


To those who know regular expressions, the csh has a limitation in its filenamewildcards. The character class wildcard does not permit exclusion ranges. In tcsh it does.For example, the wildcard test[1-3] means match filenames test1, test2 and test3. In tcshyou can use a wildcard such as test[^1-3] which means match test followed by any singlecharacter that is not a 1,2, or 3. It would match test4, or testa, but it would NOT matchtest1. This is very similar to most implementations of regular expressions, as well as thekorn shell.

Something that the tcsh does that I have not seen implemented before in shell wildcardsis a "negated match." If you use a ^ as the first character in a wildcard itmeans negate the match (note that ^ as the first character in a character class isdifferent, as described above).

Here is an example of a negated wildcard:


This will match all names in the current directory beginning with test and ending with4,5,6,7 or 8 (except names starting with a period). In other words, an ^ as the firstcharacter means, "Match everything except what this wildcard matches." Manypeople have trouble using this feature because they make the attempt with something like^test. This will not work because ^test is not a wildcard. You can trick the shell bywriting something like ^tes[t] which will match everything but the file named test,because it's now a wildcard.

Here is an illustration:

% ls
testa testb testc
% rm ^testa
rm: ^testa non-existent
% rm ^test[a]
% ls
testb testc

I guess the developers of tcsh were thinking, "Since we enhanced everything else,we might as well enhance some commands also." So they did.

For starters, korn shell users are used to using cd to change back to the previousworking directory. You can use that command in tcsh also. Another way the cd command wasenhanced is with the special alias called cwdcmd. If you set an alias by that name, itwill automatically be called after every cd command. For example, if you set it with:

alias cwdcmd 'ls -F'

every time you change directories, the ls -F command will be issued.


There is an example in the tcsh man page that shows how to use this alias to change thexterm title to reflect your current directory, except they neglected to mention how to getthe escape character into the alias.

The example above is interesting in that if you issue ls -F in a tcsh, there is reallya built-in version of ls -F that is run instead of the usual ls command. It's actuallymore like ls -aF, except that it would be faster since it's built-in and it also includesmore symbols. For example, if a soft link points to a file, it prints an @ suffix, (likels). If a soft link points to a directory, it uses a > suffix on that name. A &suffix means the soft link is broken (points to a non-existent name). And there is also anenhanced built in whereis command.

To take advantage of the many goodies in the tcsh, you need to set several specialvariables, aliases (like correct and cwdcmd) and issue tcsh only commands (like bindkey).If you put them directly in your csh startup file, they might cause errors, or be ignored.The most common method people use is to put tcsh special startup commands in the .tcshrcfile and have that file source as the usual .cshrc startup file for the "usual"aliases and variable settings. Another method is to maintain a separate .cshrc file forcsh, and make your .tcshrc startup file self contained for tcsh. Remember that if the tcshdoes not find a .tcshrc startup file, it will run the .cshrc startup file.

-- There is much more to the tcsh that we have not covered. A good bookon the subject is "Using csh & tcsh" by Paul DuBois, published by O'Reillyand Associates, 1995,