GNU/Linux >> Znalost Linux >  >> Linux

Jak zobrazit řídicí znaky (^c, ^d, ^[, …) odlišně v shellu?

Když zadáte řídicí znaky do shellu, zobrazí se pomocí toho, čemu se říká „stříška“. Escape se například zapíše jako ^[ v stříškové notaci.

Rád si přizpůsobuji svůj bash shell, aby vypadal cool. Změnil jsem například svůj PS1 a PS2 zbarvit se. Nyní chci, aby ovládací znaky získaly také jedinečný vzhled, aby byly lépe odlišitelné od běžných postav.

$ # Here I type CTRL-C to abort the command.
$ blahblah^C
          ^^ I want these two characters to be displayed differently

Existuje způsob, jak změnit zvýraznění ovládacích znaků v mém shellu?

Je možné, aby je zobrazoval tučným písmem, nebo aby se zobrazovaly v jiných barvách než běžný text?

Používám bash shell zde, ale neoznačil jsem otázku pomocí bash protože možná existuje řešení, které platí pro mnoho různých shellů.

Poznámka že nevím, na jaké úrovni zvýrazňování řídících znaků probíhá. Nejdřív jsem si myslel, že je to v samotné skořápce. Teď jsem slyšel, že je to readline který řídí, jak jsou řídicí znaky v shellech, jako je bash . Takže otázka je nyní označena readline a stále hledám odpovědi.

Přijatá odpověď:

Když stisknete Ctrl+X , váš terminálový emulátor zapíše bajt 0x18 na hlavní stranu pseudoterminálního páru.

Co se stane dále, závisí na tom, jak je nakonfigurována disciplína tty line (softwarový modul v jádře, který je umístěn mezi hlavní stranou (pod kontrolou emulátoru) a podřízenou stranou (s kterou aplikace běžící v terminálu komunikují)).

Příkaz pro konfiguraci této discipliny tty line je stty příkaz.

Při spuštění hloupé aplikace, jako je cat který si není vědom a je mu jedno, zda je jeho stdin terminál nebo ne, terminál je ve výchozím nastavení kanonický režim, kde disciplína tty line implementuje hrubý řádkový editor .

Některé interaktivní aplikace, které potřebují více než jen hrubý řádkový editor obvykle tato nastavení změňte při spuštění a obnovte je při odchodu. Moderní shelly, na jejich výzvu jsou příklady takových aplikací. Implementují svůj vlastní pokročilejší editor řádků.

Obvykle, když zadáváte příkazový řádek, shell přepne disciplínu tty line do tohoto režimu, a když stisknete enter pro spuštění aktuálního příkazu, shell obnoví normální režim tty (jak byl v platnosti před vydáním výzvy).

Pokud spustíte stty -a příkazu, uvidíte aktuální nastavení používané pro hloupé aplikace . Pravděpodobně uvidíte icanon , echo a echoctl nastavení je povoleno.

To znamená, že:

  • icanon :tento hrubý řádkový editor je povolen.
  • echo :znaky, které zadáte (které emulátor terminálu zapisuje na hlavní stranu), se ozveny zpět (zpřístupněno ke čtení emulátorem terminálu).
  • echoctl :místo toho, aby byl ozvěn asis, řídicí znaky jsou odezvěny jako ^X .

Řekněme, že zadáte A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Návrat .

Váš terminálový emulátor odešle:ABbCx18br . Linková disciplína bude echo zpět:ABb bC^Xb bb brn a aplikaci, která čte vstup ze strany slave (/dev/pts/x ) přečte ACn .

Vše, co aplikace vidí, je ACn a pouze tehdy, když stisknete Enter takže nemůže mít žádnou kontrolu nad výstupem pro ^X tam.

Související:Jaké je čtení souboru conf mezi přihlašovacím a nepřihlašovacím shellem?

Všimnete si, že pro echo , první ^H (^? u některých terminálů viz erase nastavení) vedlo k b b odesílání zpět do terminálu. To je sekvence pro přesun kurzoru zpět, přepsání mezerou, přesun kurzoru zpět, zatímco druhý ^H výsledkem je b bb b k vymazání těchto dvou ^ a X znaky.

^X (0x18) samotný byl přeložen do ^ a X pro výstup. Jako B , do aplikace se nedostal, protože jsme ho smazali pomocí Backspace.

r (také znám jako ^M ) byl přeložen do rn (^M^J ) pro echo a n (^J ) pro aplikaci.

Jaké tedy máme možnosti pro ty hloupé aplikace:

  • zakázat echo (stty -echo ). To účinně mění způsob, jakým jsou řídicí znaky odráženy, tím, že... nic neodpovídá. Ve skutečnosti to není řešení.
  • zakázat echoctl . Tím se změní způsob ovládání znaků (jiných než ^H , ^M … a všechny ostatní používané editorem řádků) se opakují. Poté jsou odezněny tak jak je. To znamená, že například znak ESC je odeslán jako e (^[ /0x1b ) bajt (který je terminálem rozpoznán jako začátek escape sekvence), ^G odešlete a (BEL, pípnutí vašeho terminálu)… Není možné.
  • vypněte editor hrubých řádků (stty -icanon ). Ve skutečnosti to není volba, protože hrubé aplikace by se staly mnohem méně použitelnými.
  • upravte kód jádra, abyste změnili chování disciplíny tty line tak, aby echo řídicího znaku odešle e[7m^Xe[m místo pouze ^X (zde e[7m obvykle umožňuje reverzní video na většině terminálů).

Možností může být použití obalu jako rlwrap to je špinavý hack pro přidání efektního editoru řádků do hloupých aplikací. Tento obal se ve skutečnosti pokouší nahradit jednoduché read() s od koncového zařízení k volání editoru readline (který mění režim disciplíny tty line).

Pokud půjdete ještě dále, můžete dokonce vyzkoušet řešení, jako je toto, které unese veškerý vstup z terminálu, aby prošel řádkovým editorem zsh (což náhodou zvýrazní ^X s v inverzním videu) spoléhající na :exec obrazovky GNU funkce.

Nyní u aplikací, které implementují svůj vlastní editor řádků, je na nich, aby rozhodly, jak bude echo je hotovo. bash používá readline pro to, co nemá žádnou podporu pro přizpůsobení způsobu ozvěny řídicích znaků.

Pro zsh , viz:

info --index-search='highlighting, special characters' zsh

zsh standardně zvýrazní netisknutelné znaky. Zvýraznění můžete upravit například pomocí:

zle_highlight=(special:fg=white,bg=red)

Pro bílé a červené zvýraznění těchto speciálních znaků.

Textová reprezentace těchto znaků však není přizpůsobitelná.

V národním prostředí UTF-8 se 0x18 vykreslí jako ^X , u378 , U7fffffff (dva nepřiřazené body kódu unicode) jako <0378> , <7FFFFFFF> , u200b (znak Unicode, který nelze ve skutečnosti vytisknout) jako <200B> .

x80 v národním prostředí iso8859-1 by bylo vykresleno jako ^� … atd.


Linux
  1. Počítání znaků každého řádku s Wc?

  2. Jak převést hex na ASCII znaky v prostředí Linuxu?

  3. získat prvních 5 znaků z každého řádku v shell skriptu

  1. Jak přiřadit výstup příkazu proměnné shellu?

  2. Jak zjistit, zda je Shell řízen z Ssh?

  3. Jak zobrazit parametry příkazového řádku linuxového jádra dané pro aktuální boot?

  1. Jak zopakovat nový řádek ve skriptech Bash Shell

  2. Jak změnit výchozí prostředí v Linuxu

  3. Jak získat PYTHONPATH v shellu?