如何在会话之间启用 ksh 命令历史记录

如何在会话之间启用 ksh 命令历史记录

如果我启动kshmksh,我的向上箭头不会执行任何操作:

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

bash但如果我开始bash并按向上箭头,它就会起作用。

$ bash
developer@1604:~$ ssh [email protected] -p 2223

如果我启动 ksh 或 mksh,则没有历史记录。我什至设置了 $HISTFILE 变量,但如果我启动一个新的 shell,仍然没有历史记录。

我能做什么呢? Korn shell 确实无法记住会话之间的历史记录,而 bash shell 可以吗?

如果我喜欢 Korn shell 并且想要更好、更广泛的历史记录,是否可以通过 ksh 使用该功能?

答案1

不,这不是真的。

如果$HISTFILE是文件名,则会话历史记录将存储在该文件中。手册中对此进行了解释。 shell 历史记录中记住的命令数量受 值的限制$HISTSIZE

我相信在执行每个命令后历史记录会刷新到文件,而不是bash在 shell 会话结束时将历史记录刷新到文件。这可能取决于ksh您使用的实现。

设置HISTFILE为文件中的文件名~/.profile(由登录 shell 读取)或 指向的文件中的文件名$ENV(由交互式 shell 读取,默认值为$HOME/.kshrcin ksh93)。默认情况下是 500 或 512 或类似的值,具体取决于您正在使用$HISTSIZE的实现。ksh这些变量都不需要导出。在执行此操作之前,历史文件不需要存在。


在评论中您提到某些 Emacs 移动和命令行编辑键不起作用。这是因为 shell 不处于 Emacs 编辑模式。将变量EDITOR(或VISUAL)设置为emacs或使用set -o emacs以启用 Emacs 命令行编辑模式。这在手册中也有解释。这些变量也不需要导出,除非您希望 shell 之外的其他程序使用它们。


概括:

在你的$HOME/.profile文件中:

export ENV="$HOME/.kshrc"

在你的$HOME/.kshrc文件中:

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

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

这已经在 OpenBSD 上用ksh93pdkshksh在 OpenBSD 上)进行了彻底的测试。我不使用mksh,但由于它是一个pdksh衍生物,我相信这也适用于该 shell。

笔记那个pdkshksh93(和bash无法共享历史文件因为它们有不同的历史格式。

bash如果您已经为和分离了初始化文件ksh,例如.bash_profile.bashrcbash.profile.kshrcksh(与export ENV="$HOME/.kshrc"in .profile),这通常不是问题。您可以ksh通过查看$KSH_VERSION(通常)来进一步区分各种实现。

答案2

一会儿。默认情况下,KSH 不接受箭头键来迭代命令历史记录。

看这个问题:

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

来自蒂姆的回答:

对于箭头键,您可以将其放入主目录中的.kshrc 文件 [(都使用,pdksh而不是 )] 中:mksh.mkshrc.kshrc

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

请注意,等号左侧的字母之前有两个下划线字符。在等号的右侧,目标是获得分配给别名的正确控制字符。该脚本执行此操作的方式是运行命令(通过 back-tics)

echo "\020"

获取分配给 __B 的 control-n 字符。

编辑(感谢 mirabilos):我在采购时删除了反引号上的内容。我被这个误导了:

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

确保您的$HISTFILE环境变量指向一个文件,然后就可以开始了。

我有pdksh,从手册页

注意:如果未设置 HISTFILE,则不使用历史文件。这与原始的 Korn shell 不同,后者使用 $HOME/.sh_history;将来,pdksh 还可能使用默认历史文件。

因为mksh它是相同的

注意:如果未设置 HISTFILE,则不使用历史文件。这与 AT&T UNIX ksh 不同。

请注意,mypdksh和 mymksh都用作$HOME/.mkshrc文件.kshrc。同样,关于 RTFM ( ) 的问题man ksh,您的实现可能会使用另一个。 (感谢 Kusalananda 对此的暗示)。

顺便说一句,您可以使用命令轻松地将 ksh 历史记录转换为 bash_history strings,并使用 sed 进行整理,如下所示:

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

答案3

我认为正在发生的事情是,从 bash 开始,您习惯于使用箭头来访问历史命令。据我所知,KSH 中没有启用这一点(除非您通过循环来实现它),除非您“set -o vi”,在这种情况下您可以使用 vi 的光标移动和文本编辑键,即: < h > left 、<j>向上、<k>向下、<l>向右、<i>插入、<x>删除字符、<d><w>删除单词等,更多详细信息这里 话虽如此,如果您在运行“history”命令时可以看到命令历史记录,那么您应该能够使用上述提示浏览历史记录。但是,如果“history”命令不输出任何内容,我认为这将是另一个问题(常见的问题是“.sh_history”文件所有权和权限)。 ^_^

相关内容