Po wpisaniu znaków kontrolnych w powłoce są one wyświetlane przy użyciu tak zwanej „notacji karetki”. Na przykład Escape jest zapisywane ^[
w notacji karetki.
Lubię dostosowywać moją powłokę bash, aby wyglądała fajnie. Na przykład zmieniłem moje PS1
i zostałem PS2
pokolorowany. Chcę teraz, aby postacie kontrolne również zyskały niepowtarzalny wygląd, aby były bardziej odróżnialne od zwykłych postaci.
$ # Here I type CTRL-C to abort the command.
$ blahblah^C
^^ I want these two characters to be displayed differently
Czy istnieje sposób, aby moja powłoka wyróżniała znaki sterujące inaczej?
Czy można wyświetlać je pogrubioną czcionką, a może wyświetlać je w innym kolorze niż zwykły tekst?
Używam tutaj powłoki bash , ale nie otagowałem tego pytania, bash
ponieważ być może istnieje rozwiązanie, które dotyczy wielu różnych powłok.
Zauważ , że nie wiem, na jakim poziomie występuje podświetlanie znaków kontrolnych. Najpierw pomyślałem, że to w samej skorupce. Teraz słyszałem, że to readline kontroluje, jak znaki kontrolne znajdują się w powłokach, takich jak bash . Pytanie jest więc otagowane readline
i wciąż szukam odpowiedzi.
bash
to jestreadline
obsługa takich rzeczy, a dla większości innych jest sterownik tty.vi
iless
często wyróżniają znaki sterujące inaczej niż zwykły tekst. Przeredaguję pytanie za pomocą tych informacji. Dziękuję Ci!zsh
który robi to po wyjęciu z pudełka.Odpowiedzi:
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 zobaczyszicanon
,echo
iechoctl
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
), odczytaAC\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, patrzerase
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^
iX
znaków.Sam
^X
(0x18) był tłumaczony na^
iX
na wyjście. JakB
, 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:
echo
(stty -echo
). To skutecznie zmienia sposób echa znaków kontrolnych, ... nie odbijając niczego. Niezupełnie rozwiązanie.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 .stty -icanon
). Nie jest to właściwie opcja, ponieważ zwykłe aplikacje stałyby się znacznie mniej przydatne.\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ć prosteread()
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:zsh
domyślnie podświetla znaki niedrukowalne. Możesz dostosować podświetlanie, na przykład: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.źródło
Zwykle mam ten kod w moim pliku .bashrc:
a następnie wywołuję tę funkcję w moim PS1
Dzięki temu, jeśli naciśniesz ^ C, zobaczysz to w monicie
Zostaną wyświetlone monity o wszystkie kody zakończenia wyjścia, które nie są „0”.
źródło