DæmonNews: News and views for the BSD community

Daemon News Ezine BSD News BSD Mall BSD Support Forum BSD Advocacy BSD Updates

Making friends with C-Shell and TC-Shell, Part I

Konrad Heuer, <kheuer@gwdg.de>

Table of Contents

1. Introduction
 1.1 Looking back into history
 1.2 The tasks of a shell

2. Old commands newly invoked - the history mechanism
 2.1 Saving commands
 2.2 Editing of command lines
 2.3 The traditional access to the history buffer

3. File name substitution and and name completion
 3.1 Substitution of filenames by special characters
 3.2 Name completion with special keys


1. Introduction

1.1 Looking back into history

As the Unix operating system was created in the seventies of the last century at the AT&T Bell Laboratories, there was only one shell, called later the Bourne-Shell (sh) after the developer. The University of California at Berkeley played a considerable role in the further development of Unix, and developed the C-Shell (csh), which offered greater comfort and was in its syntax much more strongly oriented towards the C programming language. In the later widely distributed BSD-Unix (Berkeley Software Distribution) the C-Shell dominated as the standard Shell for dialogue between the user and the system.

Today, csh and the more comfortable successor TC-Shell (tcsh) are still the default login shells on a BSD system. Despite their impressive functionality, they seem to lose popularity compared to the GNU Bourne-Again-Shell (bash) of the Free Software Foundation. This article, divided into three parts to be published in consecutive issues of the Daemon News, will show that csh and especially tcsh don't need to hide. The article is meant to be an introduction for readers new to BSD.

Please don't misunderstand: There is no need for a flame war tcsh versus bash or tcsh versus Korn-Shell (ksh) or tcsh versus Z-Shell (zsh) (which are all good shells too), but there seems to be some need to show what csh and tcsh can do.

In general, using a command-line interface is still important in a Unix-like environment, especially for system administrators. And the modern shells offer a lot of comfort to their users.

Of course, csh is now at least partially obsolete and inferior to those modern successors to the Bourne-Shell like bash, as it arose in a time when one carried on the dialogue with the computer from a remote teletypewriter. The terminals and pseudo-terminals (e.g. in windowing environments) used today allow much more comfort, for example in command-line editing, and so the TC-Shell was created as the successor to the C-Shell. It is at least as comfortable to use as the aforementioned bash, and as an interactive shell a good choice.

tcsh is available via the ports or binary package collections of the BSD systems or in source directly from the master site ftp://ftp.astron.com/pub/tcsh/. Newer FreeBSD systems as well as Darwin or Mac OS X have tcsh installed by default.

1.2 The tasks of a shell

Like all Unix-like operating systems, BSD systems consist of a kernel, a large number of utility programs, online documentation, and configuration files. In the process of system start-up, the kernel gets loaded into main memory. During normal system operation the kernel provides services to the running processes and allocates resources as needed and available.

The shell is one of the utility programs. The system starts a shell for every terminal at which a user has logged on, receives his or her commands and runs on demand further utility or application programs.

More precisely, the shell is a command-line interpreter. It analyses every entered command line and splits it up into its component pieces. The shell knows certain internal commands that it can carry out by itself, and for all other commands it tries to find and start a program of the same name. There is a large variety of internal commands, comparable to instructions of programming languages, and there are shell variables to store information temporarily. Thus the shell can be used as an interpreter for the so-called shell scripts which are programs coded in the language of the shell.

In the following, the focus will not be on shell programming, but on interactive use.


2. Old commands newly invoked - the history mechanism

2.1 Saving commands

Often, during a sequence of activities on a computer a particular cycle of commands repeats itself; or a particular, perhaps long, command must be tried out many times with small modifications until it works. For all such, or similar, cases, it is helpful and comfortable that csh and tcsh save a certain number of commands, which is determined using the shell variable history. The command

% echo $history
100

shows the number (100 as default); a possible second field refers to the format in which the saved commands are to be displayed. Please note: If one wants to read out the value of a shell variable, the name of the variable has to be preceded by a $ sign.

The number of commands to be saved can of course be changed; for example, after

% set history = 250

250 commands would be kept in the buffer. Here and in the following, the symbol % stands for the shell prompt, at which the user can enter commands. The prompt is variable, as is explained in a later part of the article.

The contents of the history buffer can be displayed using the shell command history; by default, a command number, time of command entry and the command itself will be indicated:

% history
1 16:15 echo $history
2 16:15 set history = 250
3 16:15 history

If one wishes that only the last two commands be listed, this can be entered:

% history 2
3 16:15 history
4 16:16 history 2

When the shell is terminated, e.g. because the user logs off, it can save the commands in the buffer in a history file. The default name of this file is .history in the user's home directory, but this can be changed by assigning a different file name to the shell variable histfile. Saving the history list can be enabled by setting the shell variable savehist:

% set savehist

A value assignation is possible too;

% set savehist = ( 250 merge )

means, for instance, that the content of the history buffer and the old history file should be merged, sorted with respect to time, and at most the 250 newest commands should be kept. This is particularly convenient when in parallel several shell windows on an X display are in use. Without merge as the second word, the old file contents would be completely overwritten every time a shell is left. The traditional csh does not allow specification of a second word, thus only e.g.

$ set savehist = 250

can be entered in csh.

2.2 Editing of command lines

The most obvious advance of tcsh with respect to csh is surely the possibility of editing the commands in the buffer with the help of the usual emacs or vi key commands; both are very widespread editing programs in the world of BSD and Unix.

The default setting of tcsh is often emacs and is determined during the compilation of the shell. The command

% echo $version
tcsh 6.10.00 (Astron) 2000-11-19 (i386-intel-FreeBSD)
options 8b,nls,dl,al,kan,sm,rh,color,dspm

using the shell variable version, returns the options used at compilation as well as the version number (here 6.10.00) and after the word options. As in the example, if vi does not appear, the default is emacs. Other options will be explained later if necessary.

The command

% bindkey
Standard key bindings
"^@" -> set-mark-command "^A" -> beginning-of-line
(... a lot of output ...)

returns a list of key functions; here, for example, ^A stands for the simultaneous pressing of the control key and the A key. The similarly occurring ^[ symbolizes the escape key, the operation of which precedes that of the other key. If in the list the symbol \ is followed by a number, the octal code of a key is meant.

The bindkey command can be used to switch between the emacs and vi modes:

% bindkey -e
% bindkey -v

Table 1 shows a limited but useful number key functions for editing in emacs mode. After some experimenting it's relatively easy to know them inside out.

Table 1: A choice of command-line editing functions in emacs mode
KeyUse

^A

Put the cursor at the beginning of the line

^D

Delete the character under the cursor

^E

Put the Cursor at the end of the line

^K

Cut all characters to the right of the cursor

^L

Clear the screen

^T

Transpose the character under the cursor with its left-hand neighbor

^U

Clear the whole line

^V

Quote the following character

^Y

Paste the just cut characters

Backspace

Delete the character to the left of the cursor

Up arrow

Scroll backwards through the history buffer

Down arrow

Scroll forwards through the history buffer

Left arrow

Move the Cursor one place to the left

Right arrow

Move the Cursor one place to the right

Escape N

Search forwards through the history buffer for the string already typed in

Escape P

Search backwards through the history buffer for the string already typed in

Escape _

Insert the last word of the previous command line

The most important keys for command-line editing are, of course, the arrow keys and the backspace key. They allow simple retrieval and editing of previously entered commands.

The vi editing mode will not be treated in detail; it is less useful even for users normally enjoying the vi text editor.

2.3 The traditional access to the history buffer

The traditional access to the history buffer was implemented in the C-Shell, and involves the use of two special characters which can be changed through the shell variable histchars; by default these are the characters ! and ^.

The range of functions available with this method is large, but the notation is troublesome to learn. Many of the functions can be operated more quickly using the editing possibilities from the last section, so therefore only a small but useful selection of functions will be described here primarily for csh users. Nevertheless, tcsh users and even bash users may find them useful from time to time. (Yes, bash supports some of these expressions, too!)

For instance, to repeat the last command without any modification, one can use two exclamation marks:

% who
joe ttyp2 Nov 9 14:00
% !!
who
joe ttyp2 Nov 9 14:00

User joe will serve as an example from now on. Joe is a C programmer; his current and and more or less superfluous (he knows by himself) project is to write a BASIC interpreter to reawaken the spirit of the early 1980s. (Some readers may remember the home computers of those days with build-in BASIC interpreters.)

To correct a typo in the last command, one can use the second special character ^ to replace an old string of one or more characters with a new one:

% whp
whp: Command not found.
% ^p^o
who
joe ttyp2 Nov 9 14:00

Table 2 shows these and some more selected possibilities to refer to the command history by the so-called event specifications. Please note, that command numbers can be displayed by the history command.

Table 2: A choice of traditional history event specifications
ExpressionUse

!!

Repeat the last command

!n

Repeat the command with number n

!-n

Repeat the nth-last command

!text

Repeat the last command that begins with text

!?text

Repeat the last command that contains text

!:n

Repeat the nth word of the last command

!$

Repeat the last word of the last command

!*

Repeat all arguments of the last command

^old^new

Replace in the previous command old with new and repeat the command


3. File name substitution and and name completion

3.1 Substitution of filenames by special characters

Several special characters ease the entry of filenames, in particular in the case of long pathnames, or the simultaneous naming of multiple files. These characters are substituted when comparing to file names; a procedure which is also called globbing.

The character ~ as the first character of an expression or before a slash stands for ones own home directory:

% echo ~
/usr/home/joe
% ls -F ~
tb/

If a user name follows the ~, this stands for the home directory of the user in question:

% ls ~joe/tb
Makefile ci.c tb.c tb.tex
ascii.bas help.c tb.h utils.c
bi.c io.c tb.ps

The / automatically delimits user name joe from the rest of the path name.

By the way, the shell variables user and home are set up with ones own user name and the relevant home directory.

A very helpful and well known special character is *, which substitutes any number of any characters:

% ls tb/tb.*
tb/tb.c tb/tb.h tb/tb.ps tb/tb.tex

Please note that in contrast to other operating systems, the dot (with one exception) has no special meaning, and in the above example ls -l tb/tb* would produce the same result. The exception is when the dot is the first character of a filename, thus hiding the file, and this can not be replaced by another symbol:

% ls -aF
./ .cshrc .logout tb/
../ .login .tcshrc
% echo *
tb

Another difference when comparing to other operating systems is that on Unix-like systems the expansion of special or wildcard characters like * is done by the shell and totally independent of the actual command.

The question mark is often useful, substituting exactly one character of any type:

% ls tb/tb.?
tb/tb.c tb/tb.h

There are further possibilities for the aimed naming of files:

% ls -l tb/tb.{c,h,tex}
-rw-r--r-- 1 joe nobody 838 12 Nov 13:34 tb/tb.c
-rw-r--r-- 1 joe nobody 3986 12 Nov 13:34 tb/tb.h
-rw-r--r-- 1 joe nobody 16270 12 Nov 13:34 tb/tb.tex

The curly brackets allow the creation of filenames through counting them out. The square brackets, in contrast to this, allow exactly one character from a group of characters to be substituted. The dash - can be used as an abbreviation to specify a range of characters:

% ls .[abcdefghijklmnopqrstuvwxyz]*
.cshrc .login .logout .tcshrc
% ls .[a-z]*
.cshrc .login .logout .tcshrc

Both commands are equivalent.

An extension of tcsh with respect to csh concerning file name substitution is the negation character ^ entered as the leading character:

% ls ^tb/*.c
tb/Makefile tb/ascii.bas tb/tb.h tb/tb.ps tb/tb.tex

Inside square brackets, both shells accept a leading ^ to negate:

% ls .[^.l]*
.cshrc .tcshrc

By setting the shell variable noglob, the file name substitution capability of the shell can be blocked:

% set noglob
% ls .[^.l]*
ls: .[^.l]*: No such file or directory
% unset noglob

This only really makes sense if the names of the files to be worked on do, in fact, contain many of the aforementioned special characters: It is possible to name a file * or [hello], although one really should avoid such names. By entering the unset command shown above the name substitution capability of the shell can be unblocked again.

In isolated cases, the functionality of the special characters can be blocked by quoting with single or double quotes or the \ character; the quotes quote a group of characters and the \ quotes its right-hand neighbor:

% ls "tb/*"
ls: tb/*: No such file or directory
% ls tb/tb.\*
ls: tb/tb.*: No such file or directory

3.2 Name completion with special keys

No doubt, it is tiresome to type in long file or path names; and a shell with no capability to complete file names on demand gives its user the feeling to be a looser; he or she might soon feel some craving for a graphical user interface.

When using csh or tcsh, there is no need to despair. In csh, after setting the shell variable filec, the escape key (symbolized by <ESC> below) can be used to require file name completion from the shell:

% cd tb
% set filec
% vi M<ESC>akefile

There is only one file in the working directory the name of which starts with M. Thus the abbreviation M is unambiguous, and after pressing the escape key the shell will complete the file name. If the leading and already entered part of a file name is ambiguous, there will be an acoustic warning signal, the shell will complete as much as possible, and the user will then have to add more characters.

In tcsh, name completion has been improved; the shell can complete names of files, commands, and variables! Furthermore, file name completion is programmable, but this is beyond the scope of this article. The name completion capability is always turned on; name completion can be required by pressing the tabulator key:

cd tb
vi M<TAB>akefile

As in csh, if the entered abbreviation is ambiguous, a warning signal will be given, the shell will complete as much as possible, and the user will then have to add more characters. Both shells can assist the user here; typing ^D will cause all possible completions to be listed.

Some shell variables allow to adjust the behavior of tcsh with respect to name completion:

  • If autolist is set, a list of possible completions for ambiguous shortened names is given along with the warning signal after the tabulator key is pressed (so ^D needs not to be pressed).

  • If addsuffix is set (it is set by default), a backslash is added to the end of directory names and a space to the end of all other names.

  • The variable fignore can be used to specify a list of filename suffixes, in order to exclude certain types of files in the case of ambiguity; for instance,

    % set fignore = ( .o \~ )
    

    excludes object files and backup copies of the emacs editor.

  • The acoustic warning signal can be turned off by setting nobeep, or it can be replaced by a screen flash by setting visiblebell.

The ability of tcsh to complete command or variable names is useful to reduce typing, too, but also useful if one remembers the first characters of command or variable names only:

% set autolist
% xdp<TAB>yinfo (... a lot of output ...)
% echo $st<TAB>atus
0

The utility xdpyinfo prints a lot of information about the current X display, and status is a shell variable the value of which is the exit code of the previous command (zero looks good).


Looking forward

Parts II and III will deal with the directory stack, with redirection of input and output, with job control, with alias definitions, and with start-up files. Furthermore, there will be some hints concerning advanced csh and tcsh features.

Google
Web daemonnews.org

More Articles
  • Interview with Jan Schaumann
  • Interview with Theo de Raadt
  • Book Review: Virtualization with VMware ESX Server
  • Editorial: Not Quite Dead Yet
  • The Design of OpenBGPd
  • Interview with der Mouse
  • Letter to Steve Jobs
  • Interview with Manuel Bouyer on Xen
  • Apple and Open Source
  • BSDCan 2006
  • BSD Certification Survey Results
  • Lab in a Box
  • Ike Notes on BSDCan 2005
  • BSDCan 2005 Photos
  • FreeBSD Developer Summit Pictures

  • Advertisements




    Author maintains all copyrights on this article.
    Images and layout Copyright © 1998-2006 Dæmon News. All Rights Reserved.