Quando si preme Ctrl+X, l'emulatore di terminale scrive il byte 0x18 sul lato principale della coppia pseudo-terminale.
Cosa succederà dopo dipende da come viene configurata la disciplina tty line (un modulo software nel kernel che si trova tra il lato master (sotto il controllo dell'emulatore) e il lato slave (con cui interagiscono le applicazioni in esecuzione nel terminale)).
Un comando per configurare quella disciplina tty line è il sttycomando.
Quando si esegue un'applicazione stupida come catquella non è a conoscenza e non importa se il suo stdin è un terminale o meno, il terminale è in una modalità canonica predefinita in cui la disciplina tty line implementa un editor di linee grezze .
Alcune applicazioni interattive che richiedono più di quell'editor di linea grezza in genere modificano tali impostazioni all'avvio e le ripristinano all'uscita. Le shell moderne, al loro prompt, sono esempi di tali applicazioni. Implementano il proprio editor di linee più avanzato.
In genere, mentre si immette una riga di comando, la shell inserisce la disciplina della linea tty in quella modalità e quando si preme invio per eseguire il comando corrente, la shell ripristina la normale modalità tty (come era in vigore prima di emettere il prompt).
Se esegui il stty -acomando, vedrai le impostazioni correnti in uso per le applicazioni stupide . È probabile che tu veda icanon, echoe le echoctlimpostazioni siano abilitate.
Ciò significa che:
icanon: quell'editor di linea grezza è abilitato.
echo: i caratteri digitati (che l'emulatore di terminale scrive sul lato principale) vengono ripetuti (resi disponibili per la lettura dall'emulatore di terminale).
echoctl: invece di essere riecheggiato asis, i caratteri di controllo vengono ripetuti come ^X.
Quindi, supponiamo che tu digiti A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.
Il tuo emulatore di terminale invierà: AB\bC\x18\b\r. La disciplina riga eco indietro: AB\b \bC^X\b \b\b \b\r\ne un'applicazione che legge l'input dal lato slave ( /dev/pts/x) leggerà AC\n.
Tutto ciò che l'applicazione vede è AC\n, e solo quando la tua stampa Enternon può avere alcun controllo sull'output per ^Xlì.
Noterai che per l' eco , il primo ^H( ^?con alcuni terminali, vedi le eraseimpostazioni) ha comportato \b \bl'invio al terminale. Questa è la sequenza per spostare indietro il cursore, sovrascrivere con lo spazio, spostare nuovamente il cursore indietro, mentre il secondo ha ^Hportato \b \b\b \ba cancellare quei due ^e Xcaratteri.
Lo stesso ^X(0x18) veniva tradotto in ^e Xper l'output. Ad esempio B, non è arrivato all'applicazione, poiché l'abbiamo eliminato con Backspace.
\r(aka ^M) è stato tradotto in \r\n( ^M^J) per echo e \n( ^J) per l'applicazione.
Quindi, quali sono le nostre opzioni per quelle applicazioni stupide :
- disable
echo( stty -echo). Questo cambia efficacemente il modo in cui i personaggi di controllo vengono fatti eco, non ... facendo eco a nulla. Non proprio una soluzione.
- disabilita
echoctl. Ciò cambia il modo in cui i caratteri di controllo (diversi da ^H, ^M... e tutti gli altri utilizzati dall'editor di riga) vengono ripetuti. Vengono quindi fatti eco così come sono. Cioè, ad esempio, il carattere ESC viene inviato come byte \e( ^[/ 0x1b) (che viene riconosciuto come l'inizio di una sequenza di escape dal terminale), ^Gsi invia un \a(un BEL, facendo suonare il terminale) ... Non un'opzione .
- disabilitare l'editor delle linee grezze (
stty -icanon). Non è un'opzione in quanto le applicazioni grezze diventerebbero molto meno utilizzabili.
- modifica il codice del kernel per cambiare il comportamento della disciplina tty line in modo che l' eco di un personaggio di controllo invii
\e[7m^X\e[minvece di solo ^X(qui di \e[7msolito abilita il video inverso nella maggior parte dei terminali).
Un'opzione potrebbe essere quella di utilizzare un wrapper come rlwrapquello è un trucco sporco per aggiungere un editor di linea di fantasia alle applicazioni stupide. Quel wrapper in effetti tenta di sostituire semplici read()s dal dispositivo terminale a chiamate all'editor di linea readline (che modifica la modalità della disciplina tty line).
Andando ancora oltre, potresti persino provare soluzioni come questa che dirotta tutto l'input dal terminale per passare attraverso l'editor di linee di zsh (che capita di evidenziare ^Xs nel video al contrario) facendo affidamento sulla :execfunzionalità dello schermo GNU .
Ora, per le applicazioni che implementano il proprio editor di linee, sta a loro decidere come eseguire l' eco . bashusa readline per ciò che non ha alcun supporto per personalizzare il modo in cui i personaggi di controllo vengono ripetuti.
Per zsh, vedi:
info --index-search='highlighting, special characters' zsh
zshevidenzia i caratteri non stampabili per impostazione predefinita. È possibile personalizzare l'evidenziazione con ad esempio:
zle_highlight=(special:fg=white,bg=red)
Per l'evidenziazione del bianco su rosso per quei caratteri speciali.
La rappresentazione testuale di questi personaggi non è personalizzabile.
In una localizzazione UTF-8, 0x18 saranno resi come ^X, \u378, \U7fffffff(due punti di codice unicode non assegnati) come <0378>, <7FFFFFFF>, \u200b(un carattere unicode stampabile non-veramente) come <200B>.
\x80in un locale iso8859-1 verrebbe eseguito il rendering come ^�... ecc.
bashesso èreadlinegestendo quella roba, e per la maggior parte altri è il driver TTY.