Backspace nie działa wewnątrz uruchomionego skryptu bash

8

Używam bardzo prostego skryptu, który odczytuje wiersz po wierszu i drukuje wprowadzoną linię z powrotem do terminala:

while read CMD; do
    echo $CMD
done

Działa dobrze, ale kiedy próbuję edytować wiersz ze backspaceznakiem, drukuje ^?zamiast usuwać znak. A kiedy naciskam Ctrl+ backspacewyjście jest ^H. Jak można naprawić to zachowanie, aby backspaceusuwało postać zamiast dodawać te znaki? Próbowałem stty erase '^?'polecenia, ale nie powiodło się.

vrom911
źródło
Uwaga: 16.10 zakończył swój cykl wsparcia w zeszłym miesiącu. Powinieneś jak najszybciej uaktualnić do 17.04.
Bajt Dowódca
1
Proponuję zastąpić read CMDprzez read -e CMD.
Cyrus,
1
spróbuj terminatorzamiast gnome-terminal. Działa zgodnie z oczekiwaniami
Severus Tux
1
@whtyger to zadziałało dla tego skryptu. W mojej prawdziwej sytuacji mam dane wejściowe z programu, który nie wywołuje odczytu. Nie mam możliwości zmiany skryptu programu, to był tylko przykład, który reprezentował mój problem. Czy są jakieś ustawienia globalne, w których mogę wykonać te konfiguracje dla wszystkich danych wejściowych?
vrom911
1
@Cyrus My Backspace działa tak, jak chcę - zawsze usuwa ostatni znak, nawet dla tego skryptu z pytania bez -eopcji. Ale na maszynie @ vrom911 tak nie jest. Zastanawiam się, dlaczego tak się dzieje i gdzie można to skonfigurować.
Shersh

Odpowiedzi:

6

Problem polega na tym, że istnieje wiele sposobów reprezentowania backspace, ale readpolecenie nie rozumie wszystkich z nich. Powinieneś być w stanie skonfigurować, co dokładnie jest wysyłane po naciśnięciu ← Backspaceklawisza w ustawieniach emulatora terminala.

Zakładając, że używasz gnome-terminaljako emulatora, otwórz Manu edycji i kliknij Preferencje profilu . Przejdź na kartę Kompatybilność i powinieneś uzyskać następujące opcje:

gnome-terminal → preferencje profilu → kompatybilność

Teraz możesz zmienić klawisz Backspace generuje: ustawienie. Do wyboru masz pięć poniższych opcji. Dodałem w nawiasach klamrowych, jak zachowują się w moim systemie:

  • Automatyczne (działa)
  • Control-H ( ^Hzamiast tego drukuje )
  • ASCII DEL (domyślnie, działa)
  • Sekwencja Escape ( ^[[3~zamiast tego drukuje )
  • Kasowanie TTY (działa)
Bajt Dowódca
źródło
Obecnie mam ASCII DEL. Wypróbowałem wszystkie 5 opcji, ale żadna z nich nie rozwiązała problemu.
vrom911
To jest dziwne. Czy możesz mi powiedzieć, co type readmówi i jakie $SHELL --versionraporty powłoki / wersji ?
Bajt Dowódca
Wiem, że to dziwne. Próbowałem google bardzo często, ale nie znalazłem rozwiązania, które mi odpowiada. type readmówi read is a shell builtin. i $SHELL --versionmówiGNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
vrom911
1

Miałem ten sam problem, używając bash w Gnome-Terminal.

Zauważ, że w linii poleceń backspace działa zgodnie z oczekiwaniami, ale kiedy mój program (prosty klient czatu oparty na gnieździe TCP) czyta ze standardowego wejścia, backspaceznak drukuje (powraca do ekranu) ^?zamiast kasować ostatni znak.

Użyj, # stty icanonaby zezwolić na „tryb kanoniczny (gotowany)”. Zobacz niektóre wyjaśnienia tutaj /unix/131105/how-to-read-over-4k-input-without-new-lines-on-a-terminal

Więcej informacji na temat mojego problemu / rozwiązania: Miałem problem, w którym musiałem wkleić więcej niż 4k znaków. Podczas tych badań doprowadzono mnie do powyższego linku. Kiedyś # stty -icanonwyłączałem limit 4k, ale straciłem możliwość używania backspace (kasowanie).

zrozumiałem
źródło