/xenix: Using the Korn Shell with
XENIX®
©1987 - Richard A. Bilancia - All Rights
Reserved
to be published first in the September 1987 issue of
UNIX®/World
Probably because I’ve mentioned several times in previous columns that I like the Korn shell so very much, I recently received a suggestion from Dr. Rebecca Thomas, "Since you’ve got the Korn shell for your XENIX® system why not write an installment on it? More and more people are getting this shell since the binary version is available for a reasonable price in a XENIX® environment." I think that the idea is a great one, so I’ve put together an article that will help you quickly get started with "ksh".
Once only available internally at AT&T, the now widely available Korn shell (named after it’s author, Bell Labs employee David Korn) is readily available for XENIX® users from Aspen Technologies (Parsippany, NJ) for a mere $125. I truly believe that the features of the Korn shell can make you a more proficient interactive user (a so-called "power user"). For a detailed description of the programming aspects of Korn shell scripts, you might want to read Jason Levitt’s article "The KORN Shell: An Emerging Standard," published in the September 1986 issue of UNIX®/World.
As Mr. Levitt wrote in that article, "The Korn Shell (’ksh’)... combines the functionality of the Bourne Shell programming language and the C Shell user interaction mechanisms," including command line editing and history manipulation as well as command aliasing.
What I expect to accomplish in this month’s column is to help the new "ksh" user get started with this powerful, yet easy to use shell, primarily from the focus of its interactive capabilities. To accomplish this objective, I have presented an abbreviated version of my customized "ksh" start-up files. These files are presented in Tables 1 and 2 which I’ll discuss in detail below.
Some Background.
As I mentioned above David Korn from Bell Labs wrote what we now call the Korn shell to incorporate and enhance the convenient features of the Berkeley C shell with the standard programming language conventions of the Bourne shell. He presented his accomplishments at the 1983 Summer USENIX Association Conference that was held in Toronto.
Since that time, and because AT&T made the Korn shell source code available through the AT&T on-line Toolchest, the Korn shell has steadily gained in popularity.
Aside from the AT&T based Korn shell documentation that comes with the shell, should you purchase it from Aspen Technologies, you might want to also read the "Introducing the Korn Shell" chapter found in Stephen G. Kochan and Patrick H. Wood’s UNIX® Shell Programming published by Hayden Publishing, Inc. This book is an excellent reference for both the Bourne and Korn shells.
The ".profile" Startup File.
The best way to understand some of the subtleties of any shell is to study the code created by another individual. This approach works equally well whether you want to study shell programming techniques or those shell characteristics determinable from startup files of another user.
While there is a single Bourne shell startup file, ".profile", the C shell has two startup files, ".login", and ".cshrc". The first of these files, ".login", is executed by the "/etc/login" program during the login process for a user that has indicated their login shell in their entry in the "/etc/passwd" file as the C shell. This procedure is nearly identical to the execution of the ".profile" during the login process for a user that has indicated their login shell to be the Bourne shell. The second of these files, ".cshrc", is executed every time a new sub-shell is created. The Korn shell uses a single startup file, ".profile", just as the Bourne shell, but optionally allows users to implement a second startup shell that is executed every time a new sub-shell is created.
With that focus in mine, I’d like to present abbreviated versions of my own Korn shell startup files. I should point out that my ".profile" startup file assumes that the Korn shell has already been specified in the "/etc/passwd" file.
Table 1 is an abbreviated version of my own custom ".profile" that I have developed for use with the Aspen Technologies version of AT&T’s Korn shell that I run on my Tandy 3000 HD with Santa Cruz Operation (SCO) XENIX® System V/286 version 2.2. Lines 1 through 4 of Table 1 should require little explanation as these are typical entries found in most Bourne shell startup files.
Line 6 sets the SHELL environment variable that is used by many programs to determine which shell to execute when a child shell is requested. Line 7 sets another enviroment variable, HISTFILE, that is used by the Korn shell to determine what filename should be used to store the command line history. This approach of using a file, rather than allocated memory as is done with the C shell, allows use of the history mechanism that spans different user sessions. You should note that I use a file in my home directory (the HOME environment variable is set by the "/etc/login" process) called ".ksh_hist". This is different than the default file name of ".sh_history" that is used if the HISTFILE variable is not set or is not writable.
Line 8 sets an environment variable named ENV that is used to identify the name of an optional script that is executed upon each invokation of a child shell. You will note that I have set this file name to ".kshrc" to remain at least somewhat consistant with the syntax of the C shell, which uses ".cshrc". A full description of the contents of my ".kshrc" will follow below.
Line 9 sets the environment variable HISTSIZE to what is also the default value of 128. The value of this variable is used to determine the number of previously entered commands that are accessible by the shell’s history mechanism.
The Korn shell greatly simplifies command line editing by simulating either the "vi" or "emacs" editors. The choice of these two editors can be made in several different ways, but I have chosen to do so in line 10 by setting the EDITOR environment variable to "vi". You can also use the VISUAL environment variable or the "set -o [vi | emacs]" command.
Next, in line 11, I set the PS1 environment variable (which is used to determine the first level shell prompt) to display the current working directory. Since the Korn shell automatically maintains an environment variable named PWD to store the string value of the current working directory, it becomes a trivial matter to display that value in a customized prompt.
The built-in to the Korn shell command, "cd", can be customized to look for a proper subdirectory in different places by using the CDPATH environment variable. In line 12 I set CDPATH to ".:$HOME" so that if the directory that I want to change to is not in my current working directory, my home directory is also checked. If a directory with a matching name is found there, it is then the one used to satisfy the command. I don’t recommend that you use a very long list of colon separated directory names with this option, because the results can often be very unexpected. Additionally you probably will want to use this option only in conjuction with the primary prompt set as in line 8.
In line 13 I have set the FCEDIT environment variable to "/usr/bin/vi" for use when I invoke the built-in "fc" command. More on this command later.
The TMOUT environment variable can be set, as shown in line 14, to a specified number of seconds that define the maximum number of seconds that can transpire between commands with having the Korn shell automatically log itself out. As you can see, I have used the "#" character to comment this line out because I do not like this feature.
Finally, in lines 15 and 16 are the export commands that place all of the variables set in the above lines into the environment.
Even this requirement can be avoided with proper use of the "set -o allexport" command.
The ".kshrc" Startup File.
Line 1 of the file is used to set a default "umask" value so that any files created are not readable by other users not in the same group as me. Next, in line 2 I set an option to monitor all background jobs submitted from a shell. When a background job completes, its exit status is displayed with a message. In line 3 I set an option to automatically create full pathname aliases for all commands that I invoke. This makes the subsequent execution of such commands faster as the path will not need to be searched before executing the command.
The remainder of the contents of this file is used to setup aliases for certain commands that I frequently use. Aliases can be thought of as simple shell programs, but because they are loaded into user memory, rather than stored in a separate file, execution begins much faster. When I type the abbreviation shown on the left hand side of an alias, the contents of the right hand side are executed. The first of these aliases, lines 5 through 8, is set only conditionally if the terminal variable is set for a standard ANSI console. I use this command to automatically clear the screen when I don’t want a lot of information displayed.
You will note that some of the remaining aliases have a trailing space included and others do not. This trailing space tells the Korn shell to check the next word for further alias substitution. Most of these other aliases in lines 10 through 23 deserve no further explanation, except for those on lines 11 and 23. The alias that I use for "h" invokes the "fc -l" command to display a history list of the previous commands that I have entered. The "fc" built-in command is the primary tool to manage the history mechanism of the Korn shell. There are many options to "fc" in fact the Korn shell automatically sets an alias for the "r" command to invoke "fc -e -" to allow for a simple repeat command syntax that is similar to the use of the "!" operator in the C shell.
The last alias I will discuss in the alias for "lpr" that I set in line 23. Because I often don’t have a printer attached to my Tandy 3000 HD but would like to send all output to a printer than is connected to another system connected to it with "micnet" (see my discussion of "micnet" in my column in the March 1987 issue of UNIX®/World), I use an alias to automatically start the remote program execution.
Using "ksh" interactively.
Now that all the ground work has been set, let’s begin using the Korn shell’s interactive features. First, let’s assume that I’ve been working on my terminal for quite some time and now want to see the last several commands that I’ve entered. If I typed an "h" and obtained the output shown in Table 3, I could now begin to demonstrate some of the Korn shell utility. Since my prompt shows:
/usr/rab/data > _ |
if I type:
cd - |
my prompt will now show:
/usr/spool/uucppublic > _ |
In otherwords, I can toggle back (and forth) between two directories with a built-in option to the built-in "cd" command.
To re-execute the command to read my incoming mail I can type:
r 110 |
Or, to re-execute the last invocation of word count I can type:
r wc |
Or, to send mail to another user without retyping the command I can invoke the Korn shell editor by typing <ESC> followed by several ’k’s which would scroll me through the last several commands until I reached the "mail" command, when I could use standard "vi" commands to edit and modify the line.
A single "r" will repeat the immediately previous command, while an "fc grep" will invoke the actual "vi" editor with the contents of line 121. After editing the line, and exiting the editor, the resulting command will automatically be executed.
This is nothing more than a very small sampling of what can be done with the Korn shell. The possibilities, combination and permutations are almost limitless! If you’re thinking about getting the Korn shell, go ahead--it’s worth every penny!
Table 1 - The ".profile" file
1 PATH=.:/bin:/usr/bin:/u/bin:/etc:$HOME/bin
2 MAIL=/usr/spool/mail/‘basename $HOME‘
3 TERMCAP=/etc/termcap
4 tset -r
5
6 SHELL=/usr/bin/ksh
7 HISTFILE=$HOME/.ksh_hist
8 ENV=$HOME/.kshrc
9 HISTSIZE=128
10 EDITOR=vi
11 PS1=’$PWD > ’
12 CDPATH=.:$HOME
13 FCEDIT=/usr/bin/vi
14 # TMOUT=600 ; export TMOUT
15 export PATH MAIL TERMCAP SHELL HISTFILE
16 export ENV HISTSIZE EDITOR PS1 CDPATH FCEDIT
Table 2 - The ".kshrc" file
1 umask 027
2 set -o monitor
3 set -o trackall
4
5 if [ $TERM = "ansi" ]
6 then alias cls=’echo "^[[2J^[[H"’
7 # where ’^[’ above signifies the escape character
8 fi
9
10 alias cx=’chmod +x ’
11 alias h=’fc -l ’
12 alias vcal=’vi $HOME/calendar’
13 alias exc=’vi + $HOME/expenses/car’
14 alias var=’vi + $HOME/expenses/A_R’
15 alias exm=’vi + $HOME/expenses/mail’
16 alias ex=’vi + $HOME/expenses/other’
17 alias a=’alias ’
18 alias e=echo
19 alias lc=’ls -Fa’
20 alias l=’ls -lai’
21 alias lg=’cls; exit’
22 alias rm=’rm -i ’
23 alias lpr=’remote - bilanc lpr’
Table 3 - A history listing
110 mail
111 mail dickg
112 cd /usr/spool/uucppublic
113 ls -l b*
114 more bigfile
115 mv bigfile ~/data
116 cd ~/data
117 vi bigfile
118 wc bigfile
119 cd -
120 ls -l | more
121 grep rab /etc/passwd
122 cd -
123 mail dickg
124 a
125 h >> ~/.kshrc
126 vi ~/.kshrc