2

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?

  • 1
    What does the ksh man page have to say about history? – glenn jackman Aug 16 '17 at 3:31
  • @glennjackman Nothing relevant in this case or do you know? – Niklas Rosencrantz Aug 16 '17 at 6:10
  • 3
    Practically the second mention of history in the mksh Ubuntu manpage is: "HISTFILE The name of the file used to store command history." And you say "nothing relevant"? – muru Aug 16 '17 at 7:17
  • 1
    Uh, what? Who said you must manually create the file? What does that have to do with this question, and why would it affect the relevance of the part I quoted? – muru Aug 16 '17 at 7:21
  • 1
    If that is your actual question, then ask that, while including any shell initialization files involved. Without seeing what settings you have (if any), how do we know? – muru Aug 16 '17 at 7:23
3

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).

  • It is not working. Not even if I explicitly create the file and set the env variable. – Niklas Rosencrantz Aug 16 '17 at 7:20
  • @DjDac I can't say much more without knowing what ksh implementation you are using and what the steps you are taking are. – Kusalananda Aug 16 '17 at 7:31
  • I have updated the question with more information. I try it with ksh and mksh from the Ubuntu repositories. I can also try with OpenBSD in a VM with its default ksh in the default installation mode. Maybe it is because the shell is in vi mode. I'm still trying to learn more shell syntax and its features. I'm used to using the upwards arrow and being able to search my history from ctrl+I but that history is empty if I try ksh but it works with bash. – Niklas Rosencrantz Aug 20 '17 at 14:59
  • @DjDac I updated the answer a couple of days ago, I don't know if you saw it. In particular, note that the history file can't be shared between different shell implementations (i.e. between ksh and bash for example). – Kusalananda Aug 23 '17 at 14:48
  • 1
    @thecarpy It will fail since non-login shells doesn't usually set $SHELL. I was thinking explicitly about login shells. I also don't usually switch my interactive shell between bash and ksh (I only use bash non-interactively). – Kusalananda Aug 25 '17 at 8:47
1

One moment. KSH, by default, does not accept the arrow keys to iterate through command history.

See this question:

https://stackoverflow.com/questions/1623256/make-arrow-and-delete-keys-work-in-kornshell-command-line

From Tim's answer:

For the arrow keys, you can put this into your the .kshrc file [(pdksh and mksh both use .mkshrc, not .kshrc)] in your home directory:

set -o emacs
alias __A=`echo "\020"`     # up arrow = ^p = back a command
alias __B=`echo "\016"`     # down arrow = ^n = down a command
alias __C=`echo "\006"`     # right arrow = ^f = forward a character
alias __D=`echo "\002"`     # left arrow = ^b = back a character
alias __H=`echo "\001"`     # home = ^a = start of line
alias __Y=`echo "\005"`     # end = ^e = end of line

Note that there are two underscore characters before the letters on the left side of the equal sign. On the right-hand side of the equal, the goal is to get the proper control character assigned to the alias. The way this script does that, is by running the command (via back-tics)

echo "\020"

to get the control-n character assigned to __B.

EDIT (thanks mirabilos): I removed the stuff on backticks while sourcing. I was misled by this:

See https://stackoverflow.com/questions/9449778/what-is-the-benefit-of-using-instead-of-backticks-in-shell-scripts

Make sure your $HISTFILE env variable points to a file and you should be good to go.

I have pdksh, from the man page:

NOTE: if HISTFILE isn't set, no history file is used. This is different from the original Korn shell, which uses $HOME/.sh_history; in future, pdksh may also use a default history file.

For mksh it is the same:

Note: If HISTFILE isn't set, no history file is used. This is different from AT&T UNIX ksh.

Note that my pdksh and my mksh both use $HOME/.mkshrc as .kshrc file. Again, a question of RTFM (man ksh), your implementation might use another. (thanks to Kusalananda for hinting at this).

BTW, you can convert ksh history to bash_history easily, using the strings command, and a sed to tidy up, as follows:

strings <history_file> | sed 's/^[ \t]*//' >> $HOME/bash_history

  • This may depend on what implementation of ksh one is using. All ksh shells I've been using accepts the arrow keys as expected in emacs mode (and ksh93 does in vi mode too). – Kusalananda Aug 25 '17 at 7:52
  • I only used KSH on Solaris back in the day ... this post was a trip down memory lane, reading mksh and pdksh manuals ... I also quickly installed it on my Linux box to test ... and ... you are right. However, I think $ ksh $ ^[[A^[[A^[[A^[[A^[[A hints to the fact it is not working for him. Also, .mkshrc is the startup file! – thecarpy Aug 25 '17 at 7:56
  • .mkshrc may be the default init file for interactive mksh shells, and some implementations of pdksh may use that too, but not the pdksh on my machine. With export ENV=somefile in .profile you may explicitly set what init file to use for interactive shells. – Kusalananda Aug 25 '17 at 8:05
  • This post is full of technical mistakes. pdksh does not use ~/.mkshrc, the accent gravis is also parsed during sourcing the file, etc. – mirabilos Aug 26 '17 at 22:49
  • My pdksh does use ~/.mkshrc, as stated. I do instruct to read the local manpage as other implementations might use another. As for the backticks, you are right, I blindly copied a comment from a stackoverflow ... should know better ... – thecarpy Sep 1 '17 at 22:48
1

What I think is happening is that coming from bash you are used to use the arrows to access the history commands. That, AFAIK, is not enabled in KSH (unless you go through loops to make it happen), unless you "set -o vi", in which case you can use vi's cursor movement and text editing keys, ie: < h > left, < j > up, < k > down, < l > right, < i > to insert, < x > to delete a char, < d >< w > to delete a word, etc, more details here With all that said, if you can see command history when running the "history" command, you should be able to browse through the history with the above tip. However, if the "history" command doesn't output anything, that I think would be another issue (a common gotcha is the".sh_history" file ownership and permissions). ^_^

  • Hello FanDeLaU. How does this help to save the history across sessions? – roaima Sep 21 '18 at 21:29
  • That's really useful explanation. Could you add the point about the arrow keys not working, but that history might still be saved, to your Answer? – roaima Sep 27 '18 at 13:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.