Interactive Korn Shell for Bash Users
by F. William Lynch
With thanks to Dave Herrald and Andrew Green
Which OSes use ksh?
Sometimes you might need to use an OS without bash. Fortunately, most of the features which make the bash shell an excellent interactive shell are also present in the Korn shell (my personal favorite shell). In fact, many of the Korn shell features were copied and improved upon by the developers of bash.
The following OSes either include or use ksh by default:
Solaris (and AIX?) include ksh88
xBSD and some distros of Linux include pdksh
SCO OpenServer and Unixware include ksh (88?)
Later versions of Slackware include ksh93
If you know of others, e-mail me so I can add them to the list.
The following code snippet can be used in ksh to give a bash like prompt:
export HOSTNAME=`/bin/hostname` PS1='[$USER\@$HOSTNAME ${PWD##/*/}]$ '
I discovered this more or less through trial and error, though the $ won’t change to # when running as root.
Command History (vi mode)
The fc command: a brief history lesson
Take a look at the fc (fix command) man page. This command works almost exactly like the fc command in bash. You feed it the number of your
previous history command and its execution is repeated. This command was actually introduced as history in the C shell, but has evolved
since. By default, fc allows you to edit your previous commands with the ed editor (which can be changed by modifying the FCEDIT shell variable.
Clearly, the Korn shell’s command line editing features are more advanced and easier to use, however, there are three such cases where fc can be handy:
Case 1: Repeating the Last Command Explicitly
You may already be familiar with the fc operator “r” (bash/csh equivalent is “!!”) which is a built-in alias that repeats the last command issued.
Of course, if you prefer to use the !! syntax, you can use the following alias:
alias \!\!='fc -e -'
Case 2: Repeating the Last Command with Replacement
If you’re repeating the last command with only a slight modification, fc works great also. For example, suppose you ran this command:
mv app-09.26.00.log oldlogs
And you also want to move the file app-09.25.00.log to the oldlogs directory. In this case, you could use fc to accomplish your goal in less keystrokes.
fc -e - 26=25
or, you could use the Korn shell shortcut like this:
r 26=25
or even using the alias specified above:
!! 26=25
Case 3: [ESC]-v and Full vi Editing
Alternatively, you can edit the entire command line with vi using the “v” command. This type of editing can be especially helpful for editing “for”
or “while” loops that span multiple lines. This is actually another fc alias that edits the current line in full screen vi mode. However, since the
command is executed immediately upon exiting vi, you should pay extra attention to the command syntax, especially when editing commands as root.
Command Line Editing in vi Mode
Instead of using fc to edit your previous commands, it’s usually easier to use ksh built-ins in vi mode.
You can use vi mode by setting the option like this:
set -o vi (when in ksh already) OR ksh -o vi (when launching a ksh shell)
In this mode, you’ll want to get familiar with a few commands:
Previous Command | —-> | [ESC]-k | Use this key combination to access your previous command |
Next Command | —-> | [ESC]-j | Use this key combination to access your next command (if applicable) |
Filename Completion | —-> | [ESC]-\ | Use this key combination to complete a filename, or partial portion thereof |
Filename Check | —-> | [ESC]-= | Use this key combination to show which files would complete the command at this point |
Caveats:
- There is no command completion in ksh88, though there is in ksh93.
- There is no tab completion in ksh88, though there is in pdksh and ksh93
- To use tab-complete in pdksh, you may need to use set -o vi-tabcomplete
- To use tab-complete in ksh93 you may need to use set -o viraw
Commands can be editing using the standard vi editing keys, however, the arrow keys are not standard vi editing keys.
- There is no way (that I have discovered) to use arrow keys in ksh88
- Arrow keys should work fine in pdksh
- Arrow keys in ksh93 may need special key-bindings to work. Some samples are available here from www.kornshell.com.
Finally, you can also find the last command you typed that included a certain string. This can often be faster than searching through
previous command lines one at a time. To do so, use the syntax
[ESC]-/string
where string is the text string you’re searching for. You can also use the “N” and “n” to move forward and backward in your searches, respectively.
Other ksh Interactive Features (vi mode)
Command-line Editing
In conjunction with recalling your previous commands, you can also edit these commands.
A subset of the most common editing commands are listed below.
Forward One Character | —-> | —-> | [ESC]-l |
Backward One Character | —-> | [ESC]-h | |
Delete One Character | —-> | [ESC]-x | |
Replace One Character | —-> | [ESC]-r | |
Forward End of Word | —-> | [ESC]-e | |
Backward Beginning of Word | —-> | [ESC]-b | |
Delete to End of Line | —-> | [ESC]-D | |
Insert Text (current space) | —-> | [ESC]-i | |
Insert Text (adjacent space) | —-> | [ESC]-a | |
Move Cursor to Beginning of Line | —-> | [ESC]-^ | |
Move Cursor to End of Line | —-> | [ESC]-$ |
Note: The [ESC] key is not necessary if you are currently in command-mode.
Job Control
Job control under the Korn shell actually works identically to job control under the bash shell. However, since its a very useful
interactive shell feature, I’ll summarize its uses here.
Suppose for example you want to watch the system messages on a Solaris box, you might run this command:
# tail -f /var/adm/messages
But perhaps something isn’t logging correctly and you need to make some changes to /etc/syslog.conf. You decide to send ^Z (suspend)
to your tail process like this:
^Z[1] + Stopped (SIGTSTP) tail -f /var/adm/messages
You still want the process to run however, so using the number in brackets, you send the process to the background like this:
# bg %1 [1] tail -f /var/adm/messages&
Now, you’re free to make your syslog changes, and when you’re ready to return to your tail process you’ve forgotten which job it was.
In this case, you would use the jobs command to see which jobs are tasked to the current shell like this:
# jobs [3] + Stopped (SIGTSTP) ls -al /dev | more [2] - Stopped (SIGTSTP) find / 2>&1 > /dev/null [1] Stopped (SIGTSTP) tail -f /var/adm/messages
Once you know what the job number is, you can return the job to the foreground using the command:
# fg %1 tail -f /var/adm/messages
Note that if the job number is not specified the most current active job, indicated by the “+” is
the default job. So, fg with no arguments would bring job 3 to the foreground.
Alternatively, if you wanted to kill the job at this point, this could be accomplished by using
the kill command in the following manner:
# kill %1 [1] + Terminated tail -f /var/adm/messages
Thus, we can easily see how useful job control can be, especially if you have a limited number of login shells available.
References
The following references were used in making this guide:
www.kornshell.com
Learning the Bash Shell from O’Reilly
Learning the Korn Shell from O’Reilly
About the Author
F. William Lynch is a technology consultant in Denver, CO. He spends every waking hour either in
front of a computer, practicing martial arts or watching hockey.