czytać z historią

11

Jak ustawić readhistorię obsługi wbudowanych poleceń, naciskając klawisz strzałki w górę / w dół, aby je przełączać?

Próbowałem łapać, kiedy naciskasz klawisz w górę, jednak wydaje się, że nie działa z read:

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

Wydaje się, że naciśnięcie klawiszy strzałek działa i mogę to wykryć za pomocą tego, jednak jeśli kliknę aa, to się nie powiedzie, ponieważ odczyta tylko pierwszy znak identyfikatora strzałki w górę, a trzeci jest potrzebny do rozróżnienia innej strzałki Klucze.

Tyilo
źródło

Odpowiedzi:

9

Możesz rlwrapdo tego użyć , jeśli nie masz nic przeciwko instalowaniu oprogramowania.

Prawdopodobnie będziesz chciał zachować osobny plik historii, który przechowuje historię tylko dla określonego monitu w skrypcie (tj. Unikaj mieszania z historią poleceń powłoki użytkownika).

Oto przykład, który może Ci pomóc:

#!/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

W powyższym skrypcie użytkownik może korzystać ze wszystkich funkcji GNU readline , z historią obsługiwaną z - i przechowywaną w -  ~/.myscript_history. Dostosuj w razie potrzeby.

Alternatywnie możesz użyć bash read -e, który umożliwia readline dla readwywołań, ale prawdopodobnie jego funkcja historii będzie zbyt ograniczona (tj. Prawie nieistniejąca).

mrb
źródło
10

Aby skopiować świetną odpowiedź Mike'a Stroyana z tego starego posta na liście mailowej :

Możesz użyć „history -r”, aby wczytać plik do historii powłoki i „history -s”, aby dodać każdy wiersz, który czytasz do historii. Następnie użyj historii -w, aby zapisać historię z powrotem do pliku. Oto przykład edycji edycji readline w stylu 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
Chris Pacejo
źródło
Podoba mi się to rozwiązanie bardziej niż, rlwrapponieważ (przynajmniej na moim komputerze) rlwrapnie jest w stanie płynnie obsługiwać CTRL-C, np. Spróbuj uruchomić USERINPUT=$(rlwrap -o cat)i nacisnąć CTRL-C i zobaczyć, jak zachowuje się twój terminal (uruchom resetpolecenie, aby powrócić do normalnego stanu) .
zpon
Działa to naprawdę dobrze, jeśli nie chcesz instalować dodatkowych bibliotek i jesteś zadowolony z oddzielnego pliku do zarządzania danymi wejściowymi.
Luke Exton,