читати з історії


11

Як я можу зробити readісторію підтримки вбудованих команд, натискаючи клавішу вгору / вниз, щоб перейти до них?

Я намагався знайти, коли ви натискаєте клавішу вгору, однак, схоже, це не працює read:

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

Натискання клавіш зі стрілками, здається, працює, і я можу виявити її за допомогою цього, однак, якщо натиснути aa, вона вийде з ладу, оскільки прочитає лише перший символ ідентифікатора стрілки вгору, а третя потрібна для розрізнення різної стрілки ключі.

Відповіді:


9

Ви можете використовувати rlwrapдля цього, якщо ви не проти встановити програмне забезпечення.

Ви, ймовірно, захочете зберегти окремий файл історії, який підтримує історію лише для конкретного запиту у вашому сценарії (тобто уникайте змішування з історією команд оболонки користувача).

Ось приклад, який може працювати для вас:

#!/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 з історією, яка подається з - і зберігається в -  ~/.myscript_history. Підправити по мірі необхідності.

Крім того, ви можете використовувати bash's read -e, що дозволяє читати лінію для readвикликів, але, ймовірно, ви знайдете її функціональність історії занадто обмеженим (тобто майже не існує).


10

Щоб скопіювати чудову відповідь Майка Строяна зі старої публікації списку розсилки :

Ви можете використовувати "history -r" для читання файлу в історію оболонки, а "history -s" - для додавання кожного прочитаного рядка в історію. Потім скористайтеся історією -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

Це дуже добре працює, якщо ви не хочете встановлювати додаткові libs і ви раді використовувати окремий файл для керування введенням.
Люк Екстон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.