Shell – How to enable ksh command history between sessions

command historykshmkshshell

If I start ksh or mksh, my upwards arrow does nothing:

$ ksh
$ ^[[A^[[A^[[A^[[A^[[A

But it works with bash if I start bash and press the upwards arrow.

$ bash
developer@1604:~$ ssh root@127.0.1.2 -p 2223

I have no history if I start ksh or mksh. I even set the $HISTFILE variable and still no history if I start a new shell.

What can I do about it? Is it true that the Korn shell can't remember history between sessions while the bash shell can?

If I like the Korn shell and I want a better and more extensive history, is it possible to use that functionality with ksh?

Best Answer

No, this is not true.

If $HISTFILE is a filename, then the session history will be stored in that file. This is explained in the manual. The number of commands remembered in the shell history is limited by the value of $HISTSIZE.

I believe that the history is flushed to the file after the execution of each command, as opposed to bash that flushes the history to file when the shell session ends. This may depend on which implementation of ksh you are using.

Set HISTFILE to a filename in your ~/.profile file (which is read by login shells), or in the file pointed to by $ENV (which is read by interactive shells and has the default value of $HOME/.kshrc in ksh93). $HISTSIZE is by default 500 or 512 or something thereabouts depending on the implementation of ksh you are using. Neither of these variables need to be exported. The history file does not need to exist before doing this.


In comments you mention that some Emacs movement and command line editing keys do not work. This is because the shell is not in Emacs editing mode. Either set the variable EDITOR (or VISUAL) to emacs or use set -o emacs to enable Emacs command line editing mode. This is also explained in the manual. These variable also do not need to be exported unless you want other programs than the shell to use them.


Summary:

In your $HOME/.profile file:

export ENV="$HOME/.kshrc"

In your $HOME/.kshrc file:

HISTFILE="$HOME/.ksh_history"
HISTSIZE=5000

export VISUAL="emacs"
export EDITOR="$VISUAL"
set -o emacs

This has been thoroughly tested on OpenBSD with both ksh93 and pdksh (which is ksh on OpenBSD). I don't use mksh, but since it's a pdksh derivative, I believe this would work with that shell too.

Note that pdksh and ksh93 (and bash) can not share history file as they have different history formats.

This is usually not a problem if you have separated initialization files for bash and ksh, e.g. .bash_profile and .bashrc for bash and .profile and .kshrc for ksh (with export ENV="$HOME/.kshrc" in .profile). You may further distinguish various ksh implementations by looking at $KSH_VERSION (usually).

Related Question