阅读历史


11

如何read通过按向上/向下键在内置命令支持历史记录中循环显示它们?

当您按向上键时,我尝试捕获,但是它似乎不适用于read

read -p '> ' -n 3 foo
echo
echo -n "$foo" | hexdump

按下箭头键似乎可以工作,并且可以使用它来检测到它,但是如果按下aa,它将失败,因为它将仅读取向上箭头标识符的第一个字符,而需要使用第三个字符来区分不同的箭头键。

Answers:


9

rlwrap如果您不介意安装软件,则可以使用它。

您可能需要保留一个单独的历史记录文件,该文件仅维护脚本中特定提示的历史记录(即避免与用户的Shell命令历史记录混在一起)。

这是一个可能适合您的示例:

#!/bin/sh
# Save in rlwrap_example.sh

HISTORY=$HOME/.myscript_history
USERINPUT=$(rlwrap -H $HISTORY sh -c 'read REPLY && echo $REPLY')
echo "User said $USERINPUT"

$ ./rlwrap_example.sh
hello
User said hello

在上述脚本中,用户可以使用所有GNU readline功能,其中历史记录由—提供并存储在—中  ~/.myscript_history。根据需要进行调整。

另外,您可以使用bash的read -e,它启用了readline的read调用,但是您可能会发现其历史记录功能太有限(即几乎不存在)。


10

要从此旧邮件列表帖子中复制Mike Stroyan的出色答案:

您可以使用“ history -r”将文件读入Shell的历史记录,并使用“ history -s”将读入的每一行添加到历史记录中。然后,使用history -w将历史记录保存回文件。这是vi样式阅读行编辑的示例。

#!/bin/bash
history -r script_history
set -o vi
CMD=""
while true
do
    echo "Type something"
    read -e CMD
    history -s "$CMD"
    echo "You typed $CMD"
    case "$CMD" in
        stop)
            break
            ;;
        history)
            history
            ;;
    esac
done
history -w script_history
echo stopping

我喜欢此解决方案要好于rlwrap(至少在我的机器上)rlwrap无法正常处理CTRL-C,例如,尝试运行USERINPUT=$(rlwrap -o cat)并按CTRL-C,然后查看终端的行为(运行reset命令以再次返回正常状态) 。
zpon

如果您不想安装其他库,并且很高兴使用单独的文件来管理输入,则此方法非常有用。
卢克·埃克斯顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.