Я ожидая ввода пользователя (с помощью 'read') в бесконечном цикле и хотел бы иметь историю команд, которая позволяет отображать предыдущие вводимые данные, которые уже были введены, с помощью клавиш со стрелками вверх и вниз вместо получения ^ [[A и ^ [[B. Возможно ли это?
Спасибо @ l0b0 за ваш ответ. Это привело меня в правильное русло. Поиграв с ней некоторое время, я понял, что мне также нужны следующие две функции, но мне еще не удалось их получить:
Если я нажму и добавлю что-то к предыдущей команде, я бы хотел, чтобы в истории сохранено все, а не только дополнение. Пример
$ ./up_and_down
Введите команду: hello
ENTER
Введите команду:
Вверх
Введите команду: привет
ENTER
Введите команду:
Вверх
Введите команду: вы
(вместо «привет»)
Если я не могу продолжать движение вверх, потому что я нахожусь в конце массива истории, я не хочу, чтобы курсор перемещался на предыдущую строку, вместо этого я хочу, чтобы он оставаться на месте.
Это то, что у меня есть (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