Jak obsługiwać backspace podczas czytania?

10

Jak radzić sobie z wprowadzonymi spacjami, pokazuje, ^?czy wypróbowano i jak readliczy znaki, ponieważ 12^?3już 5 znaków było kompletnych (chociaż wszystkie nie były rzeczywistymi 12^?3^?danymi wejściowymi), ale po zwróceniu monitu, dziwne. Proszę pomóż!

-bash-3.2$ read -n 5
12^?3^?-bash-3.2$
Keyshov Borate
źródło

Odpowiedzi:

10

Kiedy czytasz całą linię zwykłym read(lub read -rinnym opcjom, które nie wpływają na to zachowanie), dostarczony przez jądro edytor linii rozpoznaje Backspaceklawisz do usunięcia jednego znaku, a także kilka innych poleceń (w tym Returndo zakończenia wprowadzania linii i wyślij go). Klawisze skrótów można skonfigurować za pomocą sttynarzędzia. Mówi się, że terminal jest w trybie gotowym, gdy jego edytor linii jest aktywny. W trybie raw każdy znak wpisany na klawiaturze jest natychmiast przesyłany do aplikacji. W trybie gotowania znaki są przechowywane w buforze, a do aplikacji przesyłane są tylko pełne linie.

Aby zatrzymać czytanie po określonej liczbie znaków w celu zaimplementowania read -n, bash musi przełączyć się w tryb raw. W trybie surowym terminal nie wykonuje żadnego przetwarzania Backspaceklucza (do czasu naciśnięcia Backspacepoprzedni znak został już wysłany do bash), a bash również nie wykonuje żadnego przetwarzania (prawdopodobnie dlatego, że daje to większą elastyczność zezwalając skryptowi na wykonanie własnego przetwarzania).

Możesz przekazać opcję -ewłączenia własnego edytora wiersza bash (readline, który jest poprawnym edytorem wierszy, nie tak jak ten niezwykle surowy jądro). Ponieważ bash wykonuje edycję liniową, może przestać czytać, gdy ma żądaną liczbę znaków.

Gilles „SO- przestań być zły”
źródło
9

Użyj read -e:

$ read -e -n 5
13acX

read -e oznacza, że:

Readline (patrz Edycja wiersza poleceń ) służy do uzyskania linii.

Kiedy to zrobisz, możesz edytować dane wejściowe na dowolny sposób, w jaki piszesz w zwykłym wierszu poleceń powłoki, w tym backspace Homei tak dalej.

Michael Homer
źródło
1

readjest wbudowanym bash. (patrz type read.) Dokumentację można znaleźć za pomocą man bash:

   read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
   [...]
          -e     If the standard input is coming from a terminal, readline (see READLINE above) is used to obtain the line.
                 Readline uses the current (or default, if line editing was not previously active) editing settings.

lub możesz użyć help read:

read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
      -e                use Readline to obtain the line in an interactive shell

-ePrzełącznik umożliwia obsługę readline, który w zasadzie umożliwia wszystkie funkcje dostępne w skorupa szybka, w tym obsługę Backspace.

Dlatego read -en 5powinieneś robić, co chcesz.

michas
źródło
-e rozwiązuje problem, ale sposób, w jaki readodczytana jest „liczba wprowadzonych znaków”, pozostaje bez odpowiedzi.
Keyshov Borate