bash - 使用 `read` 时如何启用向上/向下箭头键以显示以前的输入?

标签 bash shell

我在无限循环中等待用户输入(使用“读取”),并希望拥有命令历史记录,即能够使用向上和向下箭头键显示已经输入的先前输入,而不是得到 ^[[A 和 ^[[B。这可能吗?


感谢@l0b0 的回答。它让我走上了正确的方向。玩了一段时间后,我意识到我还需要以下两个功能,但我还没有设法得到它们:

  • 如果我按下向上键并向上一个命令添加一些内容,我希望将整个内容保存在历史记录中,而不仅仅是添加内容。示例

    $ ./up_and_down
    输入命令:你好
    进入
    输入指令:
    向上
    输入指令:你好
    进入
    输入指令:
    向上
    输入命令:你
    (而不是“你好”)

  • 如果因为我在历史数组的末尾而无法继续向上移动,我不希望光标移动到上一行,而是希望它保持固定。

这是我目前所拥有的(up_and_down):

#!/usr/bin/env bash
set -o nounset -o errexit -o pipefail

read_history() {
    local char
    local string
    local esc=$'\e'
    local up=$'\e[A'
    local down=$'\e[B'
    local clear_line=$'\r\e[K'


    local history=()
    local -i history_index=0

    # Read one character at a time
    while IFS="" read -p "Enter command:" -n1 -s char ; do
        if [[ "$char" == "$esc" ]]; then 
            # Get the rest of the escape sequence (3 characters total)
            while read -n2 -s rest ; do
                char+="$rest"
                break
            done
        fi

        if [[ "$char" == "$up" && $history_index > 0 ]] ; then
            history_index+=-1
            echo -ne $clear_line${history[$history_index]}
        elif [[ "$char" == "$down" && $history_index < $((${#history[@]} - 1)) ]] ; then
            history_index+=1
            echo -ne $clear_line${history[$history_index]}
        elif [[ -z "$char" ]]; then # user pressed ENTER
            echo
            history+=( "$string" )
            string=
            history_index=${#history[@]}
        else
            echo -n "$char"
            string+="$char"
        fi
    done
}
read_history

最佳答案

使用 -e 选项和内置 history 命令的 read 选项的两种解决方案:

# version 1
while IFS="" read -r -e -d $'\n' -p 'input> ' line; do 
   echo "$line"
   history -s "$line"
done

# version 2
while IFS="" read -r -e -d $'\n' -p 'input> ' line; do 
   echo "$line"
   echo "$line" >> ~/.bash_history
   history -n
done

关于bash - 使用 `read` 时如何启用向上/向下箭头键以显示以前的输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6788777/

相关文章:

bash - 如何在 bash 脚本中标记 std 输出

linux - 在 bash 中迭代数据文件

bash - zsh 更改提示输入颜色

macos - 寻找 。并替换为 . & 新队 & ;在 OSX 中(对于新手来说)

linux - 如何获取包含 T 日期作为文件名一部分的文件计数

json - 如何在以下输出中获取过去 7 天的信息

linux - Bash 脚本在杀死它自己及其所有子进程的 PGID 后没有被杀死

javascript - Node shell 脚本上没有这样的文件或目录

linux - shell - 显示 agrep 中最佳匹配的错误数

linux - 无法通过管道传输 wget HTTP header 以进行 grep 处理