Po naciśnięciu Ctrl+Xemulator terminala zapisuje bajt 0x18 po stronie master pary pseudo-terminali.
To, co stanie się potem, zależy od tego, jak skonfigurowana jest dyscyplina linii tty (moduł oprogramowania w jądrze, który znajduje się między stroną główną (pod kontrolą emulatora) a stroną podrzędną (z którymi aplikacje działające w terminalu wchodzą w interakcje)).
Poleceniem skonfigurowania tej dyscypliny linii tty jest stty
polecenie.
Podczas uruchamiania takiej głupiej aplikacji cat
nie jest ona świadoma i nie ma znaczenia, czy jej standardowe wejście jest terminalem, czy nie, terminal jest w domyślnym trybie kanonicznym , w którym dyscyplina linii tty implementuje prosty edytor linii .
Niektóre interaktywne aplikacje, które wymagają więcej niż tego prostego edytora linii, zwykle zmieniają te ustawienia podczas uruchamiania i przywracają je po wyjściu. Nowoczesne powłoki, na ich polecenie, są przykładami takich aplikacji. Wdrażają własny, bardziej zaawansowany edytor linii.
Zazwyczaj podczas wprowadzania wiersza poleceń powłoka wprowadza dyscyplinę linii tty w tym trybie, a po naciśnięciu klawisza enter w celu uruchomienia bieżącego polecenia powłoka przywraca normalny tryb tty (tak jak działał przed wydaniem monitu).
Jeśli uruchomisz stty -a
polecenie, zobaczysz bieżące ustawienia używane dla głupich aplikacji . Prawdopodobnie zobaczysz icanon
, echo
i echoctl
ustawienia są włączone.
Oznacza to, że:
icanon
: ten edytor linii surowej jest włączony.
echo
: znaki, które wpisujesz (które emulator terminala zapisuje po stronie master) są odbijane echem (udostępniane do odczytu przez emulator terminala).
echoctl
: zamiast echa asis, znaki kontrolne są echo jako ^X
.
Powiedzmy, że piszesz A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.
Terminal Emulator wyśle: AB\bC\x18\b\r
. Dyscyplina liniowa wyświetli echo : AB\b \bC^X\b \b\b \b\r\n
a aplikacja, która odczyta dane wejściowe od strony slave ( /dev/pts/x
), odczyta AC\n
.
Wszystko, co widzi aplikacja, jest dostępne AC\n
tylko po naciśnięciu przycisku, Enterdzięki czemu nie może mieć żadnej kontroli nad danymi wyjściowymi ^X
.
Zauważysz, że dla echa , pierwszy ^H
( ^?
z niektórymi terminalami, patrz erase
ustawienie) spowodował \b \b
odesłanie z powrotem do terminala. Jest to sekwencja cofania kursora, nadpisywania spacją, cofania kursora z powrotem, podczas gdy druga ^H
spowodowała \b \b\b \b
usunięcie tych dwóch znaków ^
i X
znaków.
Sam ^X
(0x18) był tłumaczony na ^
i X
na wyjście. Jak B
, nie sprawiają, że do wniosku, że my usunął go z Backspace.
\r
(aka ^M
) został przetłumaczony na \r\n
( ^M^J
) dla echa i \n
( ^J
) dla aplikacji.
Jakie są nasze opcje dla tych głupich aplikacji:
- disable
echo
( stty -echo
). To skutecznie zmienia sposób echa znaków kontrolnych, ... nie odbijając niczego. Niezupełnie rozwiązanie.
- wyłącz
echoctl
. Że zmienia znaki sterujące sposób (inne niż ^H
, ^M
... i wszystkie inne te używane przez edytor linia) są echem. Są one następnie odtwarzane w niezmienionej formie. Oznacza to na przykład, że znak ESC jest wysyłany jako \e
( ^[
/ 0x1b
) bajt (który jest rozpoznawany przez terminal jako początek sekwencji ucieczki), ^G
wysyłasz \a
(BEL, co powoduje, że twój terminal emituje sygnał dźwiękowy) ... Brak opcji .
- wyłącz edytor linii raw (
stty -icanon
). Nie jest to właściwie opcja, ponieważ zwykłe aplikacje stałyby się znacznie mniej przydatne.
- edytuj kod jądra, aby zmienić zachowanie dyscypliny linii tty, dzięki czemu echo znaku sterującego wysyła
\e[7m^X\e[m
zamiast po prostu ^X
(tutaj \e[7m
zwykle włącza odwrotne wideo w większości terminali).
Opcją może być użycie takiego opakowania rlwrap
to brudny hack, aby dodać fantazyjny edytor linii do głupich aplikacji. To opakowanie próbuje zastąpić proste read()
s od urządzenia końcowego na wywołania edytora linii readline (które zmieniają tryb dyscypliny linii tty).
Idąc jeszcze dalej, można nawet spróbować rozwiązania, takie jak ten , który przechwytuje wszystkie dane wejściowe z terminala, aby przejść przez edytor linii zsh (co zdarza się atrakcją ^X
s w negatywie) powołując się na ekranie GNU :exec
funkcji.
Teraz w przypadku aplikacji, które implementują własny edytor linii, to od nich zależy, jak echo zostanie wykonane. bash
używa readline dla tego, co nie ma żadnego wsparcia w dostosowywaniu sposobu wyświetlania echa znaków kontrolnych.
Na zsh
stronie:
info --index-search='highlighting, special characters' zsh
zsh
domyślnie podświetla znaki niedrukowalne. Możesz dostosować podświetlanie, na przykład:
zle_highlight=(special:fg=white,bg=red)
Dla biało-czerwonego podświetlenia dla tych znaków specjalnych.
Tekstowej reprezentacji tych znaków nie można jednak dostosowywać.
W UTF-8, 0x18 będzie wyświetlany jako ^X
, \u378
, \U7fffffff
(nieprzypisane dwa punkty kodowe Unicode) jako <0378>
, <7FFFFFFF>
, \u200b
(a nie-naprawdę druku znaków Unicode) jako <200B>
.
\x80
w lokalizacji iso8859-1 będą renderowane jako ^�
... itd.
bash
to jestreadline
obsługa takich rzeczy, a dla większości innych jest sterownik tty.