![]() |
|
| Daemon News Ezine | BSD News | BSD Mall | BSD Support Forum | BSD Advocacy | BSD Updates |
Making friends with C-Shell and TC-Shell, Part IKonrad Heuer, <kheuer@gwdg.de>
Table of Contents1. Introduction1.1 Looking back into history 1.2 The tasks of a shell
2. Old commands newly invoked - the history mechanism
3. File name substitution and and name completion
1. IntroductionAs 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.
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 mechanismOften, 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.
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.
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.
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.
3. File name substitution and and name completion
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
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:
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 forwardParts 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. |