Скрипт bash: Как реализовать собственный механизм истории? - PullRequest
7 голосов
/ 15 февраля 2011

Я реализую интерактивный скрипт bash, аналогичный клиенту MySQL, /usr/bin/mysql. В этом сценарии мне нужно выполнить различные типы «команд». Мне также нужно предоставить механизм истории, посредством которого пользователь может использовать клавиши стрелок вверх / вниз для прокрутки команд, введенных до сих пор.

Фрагмент, указанный здесь ( Пример 15-6, Обнаружение клавиш со стрелками ), не совсем соответствует тому, что я хочу. Я действительно хочу следующее:

  1. Клавиши со стрелками вверх / вниз должны работать в бесшумном режиме. Это означает, что они не должны отображать коды своих символов на терминале.

  2. Однако остальные ключи (которые будут использоваться для чтения имен команд и их аргументов) не должны работать в режиме без вывода сообщений.

Проблема с read -s -n3 заключается в том, что он не удовлетворяет моим одновременно противоречивым требованиям режима эхо-сообщений и в режиме эха, основанном исключительно на коде символа. Кроме того, значение -n3 будет работать для клавиш со стрелками, но для других / обычных клавиш не будет «возвращать управление» вызывающей программе, пока не будут использованы 3 символа.

Теперь я могу попробовать -n1 и вручную собрать ввод, по одному символу за раз (чёрт!). Но проблема переключения тихого / эхо-режима на основе символьного кода все еще будет сохраняться!

Кто-нибудь пробовал эту вещь в bash? (Примечание: я не могу использовать C и другие языки сценариев, такие как Perl, Python и т. Д.)

EDIT

Продолжая с ответом Денниса ... Вам также необходимо вручную добавить нужные записи в историю с помощью history -s, например ...

while read -e x; do
    history -s "$x"
    # ...
done

Ответы [ 3 ]

5 голосов
/ 15 февраля 2011

Вы можете использовать read -e, чтобы read использовать readline.Он будет обрабатывать ваши клавиши курсора и вести историю для вас.Вам также нужно будет вручную добавить нужные записи в историю через history -s, например:

while read -e x; do
    history -s "$x"
    # ...
done
2 голосов
/ 16 февраля 2011

rlwrap имеет специальный режим «одного выстрела», который заменяет команду «read».Если хотите, каждому вхождению этой команды в вашем скрипте может быть присвоен свой собственный список слов истории и завершения.

Используйте его так:

REPLY=$(rlwrap -o cat)

или, указав файл истории исписок завершения:

REPLY=$(rlwrap -H my_history -f  my_completions -o cat)
2 голосов
/ 15 февраля 2011

MySQL и Bash используют библиотеку Readline для реализации этого. Может быть, вы можете использовать что-то вроде rlwrap или rlfe ?

...