Red Hat Linux: Using PdkshUsing pdkshIn the last chapter, you saw the Bourne Again Shell (bash) in some detail.
Not everyone wants to use the bash shell, so several other shells are included
with most Linux systems. One of them is pdksh, a variation on the Korn Shell.
In this chapter, we look at the pdksh shell and how it can be efficiently
used. After reading this chapter, you will be familiar with the following
topics:
We will also look at how you can customize your copy of pdksh, as well as
several of the important commands and variables used by the shell. The Public Domain Korn Shell (pdksh) The Korn shell, written by David Korn, was the third mainstream shell written
for UNIX. Because of this, it incorporated many of the features of the Bourne
and C shells (which were the first two shells). Because of the Korn shell's
popularity among UNIX users, a version was developed for Linux called the Public
Domain Korn Shell, or pdksh. The current version of the Public Domain Korn Shell does not support all of
the features that exist in the commercial version of the Korn shell. It does
support most of the main features, however, and adds a few new features of its
own. Often, when you are entering commands at the command line, the complete text
of the command is not necessary in order for pdksh to be able to determine what
you want to do. Command-line completion enables you to type in a partial
command, and then by entering a key sequence, tell pdksh to try to finish the
command for you. pdksh does not default to allowing the user to perform command-line
completion. You must enter a command to tell pdksh that you want to be able to
use command-line completion. In order to enable command-line completion, enter
one of the following commands: set -o emacs This causes pdksh to accept command editing that is similar to emacs or vi.
Choose the editor that you are most familiar with, and use the basic editor
commands for command-line editing.
After the command-line completion function has been enabled, you can perform
command-line completion by pressing the Esc key twice (when using emacs
command-line editing), or by pressing \ (when using vi command-line editing).
For example, if your current directory contains the files News/ bin/ games/ mail/ sample.text test/ and you want to edit the file sample.text using the vi text editor, you could
enter the following command: vi sample.text After the s is typed, the only file that you could be referring to is
sample.text, because it is the only file in the current directory that begins
with the letter s. To get pdksh to finish the command when you are using emacs-style
command editing, you must press the Esc key twice after you type the letter s:
To get pdksh to finish the command when you are using vi command editing, you
must press the \ key after you type the letter s: Either of these commands causes pdksh to finish the line for you and display
the result on the screen. The command does not execute until you press the Enter
key. This is done to give you a chance to confirm that the command pdksh came up
with is the command that you really intended. If the sample.text file is not the only file in the directory that begins
with the letter s, pdksh completes the command as far as it can and then beeps,
indicating that it needs more information to complete the command.
Wildcards The pdksh shell makes typing commands easier by enabling the user to use
wildcards. pdksh supports the same wildcards that bash does: * matches any character and any number of characters. ? matches any single character. [...] matches any single character contained within the brackets. The * wildcard can be used in a way that is similar to command-line
completion. For example, if the current directory contains the files and you want to edit the sample.text file using the vi text editor, you can
perform this task by using the following wildcard: The * matches any character (and any number of characters), so pdksh replaces
s* with sample.text (the only file in the directory that matches the wildcard
pattern). This works reliably if there is only one file in the directory that starts
with the letter s. If more than one file starts with the same letter, the shell
tries to replace s* with the list of filenames that match the wildcard pattern,
and runs vi on the first file in this list. After you quit editing the first
file, the second file in the list is loaded into vi, and so on for each file
that matched the wildcard pattern. If you intended to edit more than one file,
this would be fine, but if you only wanted to edit the sample.text file, this
command would not work the way you expected it to. A more practical situation in which to use the * wildcard is when you want to
execute the same command on multiple files that have similar filenames. For
example, assume that the current directory contains the following files: News/ bin/ games/ mail/ sample.text temp1.out If you want to delete all of the files with an .out extension, you can do it
by entering the following command: In this case, pdksh replaces *.out with the names of all of the files in the
directory that match the wildcard pattern. After pdksh performs this
substitution, the following command is processed: The rm command is invoked with the arguments of temp1.out, temp2.out, and
temp3.out. The ? wildcard functions in a similar way to the * wildcard, except that the
? wildcard matches only a single character. Assuming the same directory contents
as in the previous example, the ? wildcard can be used to delete all of the
files with the .out extension by entering the following command: The [...] wildcard enables you to specify characters or ranges of characters
to match. To print all of the files in the previous example that have the .doc
extension, enter one of the following two commands: rm temp[123].out Command History The pdksh shell supports a command history in much the same way as bash. The
pdksh shell keeps track of the last HISTSIZE commands that have been entered (HISTSIZE
is a user-definable pdksh variable). pdksh stores the text of the last HISTSIZE commands in a history list. When
you log in, the history list is initialized from a history file. The filename of
the history file can be set using the HISTFILE pdksh variable. The default
filename for the history file is .ksh_history. This file is located in your home
directory. Notice that the file begins with a ., meaning that the file is
hidden, and it appears in a directory listing only if you use the -a or -A
option of the ls command. The shell provides several ways of accessing the history list. The simplest
way is to scroll through the commands that have been previously entered. In
pdksh, this is done differently depending on whether you are using emacs or vi
command editing. If you are using emacs command editing, you scroll up through the history
list by pressing Ctrl-p, and you scroll down through the list by pressing
Ctrl-n. If you are using vi command-line editing, you scroll up through the
history list by pressing either the k or - key, and you scroll down through the
history list by pressing j or +.
The command that is on the command line can be edited. The pdksh shell
supports a complex set of editing capabilities (most of which are beyond the
scope of this book). You can use the left and right arrow keys to move along the
command line. You can insert text at any point and delete text from the command
line by using the backspace or delete keys. Most users should find these simple
editing commands sufficient; for those who do not, there are many other more
complicated ways of editing the command line.
Another method of using the history file is to display and edit it using fc
(fix command), the built-in pdksh shell command. The history command was left
out of the pdksh shell because all of its functionality could be provided by the
fc command.
The fc command is used to edit the command history. It has a number of
options, as is illustrated in the following command syntax: All options given in braces are optional. The -e portion of the command can
be used to specify the text editor that is to be used for editing the commands
in the command history. The first and last options are used to select a range of
commands to take out of the history list. First and last can refer either to the
number of a command in the history list, or to a string that fc tries to find in
the history list. The -n option is used to suppress command numbers when listing the history
commands that matched the specified range. The -r option lists the matched
commands in reverse order. The -l command lists the matched commands to the
screen. In all cases except for the -l option, the matching commands are loaded
into a text editor. The text editor used by fc is found by taking the value of ename if the -e
option was used. If this option was not used, fc uses the editor specified by
the variable FCEDIT. If this variable does not exist, fc uses the value of the
EDITOR variable. Finally, if none of these variables exists, the editor chosen
is vi. If you enter the fc command with no arguments, it loads the last command that
was entered into the editor. Remember that when you exit the editor, fc attempts
to execute any commands that are in the editor. The easiest way to understand what the fc command does is to look at a few
examples: fc loads the last command into the default editor. fc -l lists the last 16 commands that were entered. fc -l 5 10 lists the commands with history numbers between 5 and 10,
inclusive. fc 6 loads history command number 6 into the default editor. fc mo loads into the default editor the most recent command that
starts with the string mo. Aliases Another way pdksh makes life easier for you is by supporting command aliases.
Command aliases are commands that you can specify and execute. Alias commands
are usually abbreviations of other commands. You tell pdksh to execute a Linux command whenever it encounters the alias.
For example, if you have a file in your directory that holds a list of things
that you must do each day, and you typically edit the file every morning to
update it, you might find yourself entering the following command on a regular
basis: Because you are entering this command quite often, you might be inclined to
create an alias for it to save yourself some typing. Instead of typing this
command every time you want to edit the file, you can create an alias called ttd
that causes the longer command to be executed. From the time that you enter the alias command until the time you exit from
pdksh, the ttd command causes the longer command to be executed. If you decide
after you enter an alias that you no longer want that alias, you can use the
pdksh unalias command to delete the alias: After you use the unalias command to remove an alias, the alias no longer
exists, and trying to execute it causes pdksh to report Command not found. The following are some aliases that you might want to define: alias ll='ls -l' alias log='logout' alias ls='ls -F' If you are a DOS user and you prefer to use DOS file commands, you may also
want to define the following aliases: alias dir='ls' alias copy='cp' alias rename='mv' alias md='mkdir' alias rd='rmdir'
If you enter the alias command without any arguments, it prints all of the
aliases that are already defined to the screen. There is a way to make sure that
all of your alias commands get executed each time you start pdksh. Input Redirection Input redirection is used to change the source of input for a command.
Typically, when a command is entered in pdksh, the command expects some kind of
input in order to do its job. Some of the simpler commands must get all of the
information that they need passed to them on the command line. The rm command,
for example, requires you to tell it on the command line which files you want to
delete; if you do not specify any files it issues a prompt telling you to enter
rm -h for help. Other commands require more elaborate input than a simple directory name. The
input for these commands is typically found in a file. For example, the wc (word
count) command counts the number of characters, words, and lines in the input
that was given to it. If you enter the wc command with a filename as an
argument, wc returns the number of characters, words, and lines that are
contained in that file. An example of this is wc test Another way to pass the contents of the test file to wc as input is to change
(or redirect) the input of the wc command from the terminal to the test file.
This results in the same output. The < character is used by pdksh to redirect
the input to the current command from the file following the character. So,
redirecting wc's input from the terminal to the test file is done by entering
the following command: wc < test Input redirection is not used too often because most commands that require
input from a file have an option to specify a filename on the command line.
There are times, however, when you will come across a program that does not
accept a filename as an input parameter, and yet the input that you want to give
to the command exists in a file. Whenever this situation occurs, you can use
input redirection to get around the problem. Output Redirection Output redirection is more commonly used than input redirection. Output
redirection enables you to redirect the output from a command into a file, as
opposed to having the output displayed on the screen. There are many situations in which this capability can be very useful. For
example, if the output of a command is quite large and does not fit on the
screen, you might want to redirect it to a file so you can later view it using a
text editor. Output redirection is done in much the same way as input
redirection. Instead of using the < symbol, the > symbol is used. To redirect the output of an ls command into a file named directory.out, the
following command is used: ls > directory.out Pipelines Pipelines are a way to string together a series of commands. This means that
the output from the first command in the pipeline is used as the input to the
second command. You can tell pdksh to create a pipeline by typing two or more
commands separated by the | character. The following is an example of using a
pdksh pipeline: This is a fairly common pipeline. Here, the contents of test.file (the output
from the cat command) are fed into the input of the sort command. The sort
command, without any options, sorts its input alphabetically by the first field
in the input. The sorted file is then piped into the uniq command. The uniq
command removes any duplicate lines from the input. If test.file contains the
lines Sample dialog the output from the pipeline is the following: Hello there All of the lines in the file have been sorted by the first word in the line,
and one of the Hello there lines has been removed because of the uniq command.
Shell Prompts pdksh has three levels of user prompts. The first level is what the user sees
when the shell is waiting for a command to be typed. (This is what you normally
see when you are working with the shell.) The default prompt is the $ character.
If you do not like the dollar sign as the prompt or prefer to customize the
prompt to your own requirements, you can do so by setting the value of the PS1
pdksh variable. To set a variable, give the name and equal sign, and the string you want to
set it to. Make sure you do not place any spaces on either side of the equal
sign, or the shell will not interpret your command properly. For example, the
line sets the shell prompt to the string ! Tell me what to do. The pdksh shell
keeps track of how many commands have been entered since it was started. This
number is stored into the shell variable called !. When you include the ! in the
prompt, it displays the current command number in the prompt. The previous
prompt command causes the command number followed by the string Tell me what to
do to be displayed on the command line each time pdksh is expecting you to enter
a command. The second level of prompt is displayed when pdksh is expecting more input
from you in order to complete a command. The default for the second level prompt
is >. If you want to change the second level prompt, you can do so by setting
the value of the PS2 pdksh variable, as in the following example: This causes the string I need more information to be displayed on the command
line whenever pdksh needs something from you to complete a command. pdksh does not support the advanced prompt options that bash supports. There
is not a predefined set of escape codes that you can put in a pdksh prompt
variable to display such items as the time or current working directory. You
can, however, put other pdksh variables into a prompt variable. For example, the
following two prompts are valid: PS1="(LOGNAME) " The first example causes your prompt to be equal to your UNIX user name. The
second example causes your prompt to be the current working directory. The
single quotes are needed here so that the value of the PWD variable does not get
assigned to the variable only the first time it is executed. If you use double
quotes, the PWD variable is evaluated only when the command is first entered.
(The prompt would always be the directory name of the directory that you are in
when you enter the command.) The single quotes cause the value of the PS1
variable to be equal to the current value of the PWD variable. Job Control Job control is the capability to control the execution behavior of a
currently running process. Specifically, you can suspend a running process and
cause it to resume running at a later time. The pdksh shell keeps track of all
of the processes that it started, and you can suspend a running process or
restart a suspended one at any time during the life of that process. Pressing the Ctrl-Z key sequence suspends a running process. The bg command
restarts a suspended process in the background, and the fg command restarts a
process in the foreground. These commands are most often used when a user wants to run a command in the
background but accidentally starts it in the foreground. When a command is
started in the foreground, it locks the shell from any further user interaction
until the command completes execution. This is usually not a problem, because
most commands only take a few seconds to execute. If the command you are running
is going to take a long time, you typically start the command in the background
so that you can continue to use pdksh to enter other commands while it completes
running. If you start a command in the foreground that is going to take a long time,
your shell may be tied up for several minutes. If you have done this and want to
continue executing the command in the background, enter the following: control-z This suspends the command and restarts it in the background. The command
continues to execute, and you have the control of pdksh. Key Bindings One useful feature that pdksh supports, which is lacking in the Bourne Again
Shell, is key bindings. This feature enables you to change the behavior of key
combinations for the purpose of command-line editing. If, for example, you do not like the fact that you have to use the emacs key
sequence Ctrl-P to move up in the history buffer, you can change the key
sequence for that command to something else. The syntax for doing the key
binding is the following: This feature effectively enables you to customize pdksh to have the exact
feel that you want. One of the most commonly used key bindings is to bind the
up, down, left, and right arrows to be used as they are in bash (for scrolling
up and down the history list, and for moving left and right along the command
line). This binding is typically found in your .kshrc file, which is the startup
file for the shell (it is read whenever the shell starts). The bind commands that are needed to create these bindings are as follows:
bind '^[['=prefix-2 The following list gives some of the most useful editing commands that you
can use for binding keys, along with the default binding and a description of
each. You can get a listing of all of the editing commands that pdksh supports
by typing the bind command without any arguments. abort (^G) is used to abort another editing command. It is most
commonly used to stop a history list search. backward-char (^B) moves the cursor backward one character. This
command is often bound to the left arrow key. backward-word (^[b) moves the cursor backward to the beginning of a
word. beginning-of-line (^A) moves the cursor to the beginning of the
command line. complete (^[^[) tells pdksh to try to complete the current command.
copy-last-arg (^[_) causes the last word of the previous command to
be inserted at the cursor position. delete-char-backward (ERASE) deletes the character that is to the
left of the cursor. delete-char-forward deletes the character to the right of the cursor.
delete-word-backward (^[ERASE) deletes the characters to the left of
the cursor back to the first white space character that is encountered.
delete-word-forward (^[ deletes the characters to the right of the
cursor up to the first character that occurs after a whitespace
character. down-history (^N) moves down one line in the history list. This
command is often bound to the down arrow key. end-of-line (^E) moves the cursor to the end of the current line. forward-char (^F) moves the cursor forward one character. This
command is often bound to the right arrow key. forward-word (^[F) moves the cursor forward to the end of a word. kill-line (KILL) deletes the current line. kill-to-eol (^K) deletes all of the characters to the right of the
cursor on the current line. list (^[?) causes pdksh to list all of the possible command names or
filenames that can complete the word in which the cursor is currently
contained. search-history (^R) searches the history list backward for the first
command that contains the inputted characters. transpose-chars (^T) exchanges the two characters on either side of
the cursor. If the cursor is at the end of the command line it switches
the last two characters on the line. up-history (^P) moves up one command in the history list. This
command is often bound to the up arrow key. Customizing Your pdksh Many ways of customizing pdksh have been described in this chapter. Until
now, though, the changes that you made only affected the current pdksh session.
As soon as you quit pdksh, all of the customizations that you made are lost.
There is a way of making the customizations more per-manent. This is done by storing all of your customizations in a pdksh initialization
file. Users can put commands into this file that they want to be executed each
and every time pdksh is started. Examples of commands that are typically found
in this file are aliases and initializations of variables (such as the prompts).
In order to set up your customization file, you must tell pdksh where to look
for the initialization file. This is different than with bash. The bash shell
automatically knew where to look for its customization file. To tell pdksh where
to look for the customization file, you must create a file in your home
directory called .profile. This file is read and all of the commands in the file
are executed each time you log into the system. A sample of the commands that you should place in your .profile file are as
follows: export ENV=$HOME/.kshrc The first line in the .profile file sets the ENV variable. This is the
variable that pdksh looks at to find the initialization file that it should use.
If you plan to customize pdksh, you should tell pdksh to look for a file in your
home directory. The filename .kshrc is often used as the pdksh initialization
filename, but you can pick another name if you want. If you are not planning to customize pdksh, you can set the ENV variable to
be equal to the system default pdksh initialization file. This file is in the
/etc directory, and is called ksh.kshrc. The second line in the .profile file sets the EDITOR variable. This is used
by the .kshrc initialization file to determine what type of command-line editing
commands to use for your session. If you prefer to use vi command-line editing,
you can set this variable to be equal to vi. Listing 11.1 shows most of what is contained in the system's default
ksh.kshrc file. If you want to add your own customizations to pdksh, you should
copy this file into your home directory and then add the customizations that you
want to your own copy of the file.
Listing 11.1. Default ksh.kshrc file. # NAME pdksh Commands Here are some of the most useful built-in pdksh commands: . reads and executes the contents of the file. alias is used to set aliases, command nicknames that can be defined
by the user. bg (background command) forces a suspended process to continue to
execute in the background. cd (change working directory) changes the current working directory
to the directory specified. exit terminates the shell. export causes the value of a variable to be made visible to all
subprocesses that belong to the current shell. fc (fix command) used to edit the commands that are in the current
history list. fg (foreground command) forces a suspended process to continue to
execute in the foreground. kill is used to terminate another process. pwd (print working directory) prints to the screen the directory in
which the user is currently working. unalias is used to remove aliases that have previously been defined
using the alias command. pdksh Variables Some of the most useful pdksh variables are listed next, including the
variable name, a short description, and default value (if one exists). EDITOR, FCEDIT The default editor for the fc bash command. HISTFILE The name of the file that is used to store the command
history. HISTSIZE The size of the history list. HOME The HOME directory of the current user OLDPWD The previous working directory (the one that was current
before the current directory was entered). PATH The search path that bash uses when looking for executable
files. PS1 The first level prompt that is displayed on the command line. PS2 The second level prompt that is displayed when a command is
expecting more input. PWD The current working directory. SECONDS The number of seconds that have elapsed since the current
bash session was started. |