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