Lorsque vous appuyez sur Ctrl+X, votre émulateur de terminal écrit l'octet 0x18 sur le côté maître de la paire de pseudo-terminaux.
Ce qui se passe ensuite dépend de la configuration de la discipline de ligne tty (un module logiciel dans le noyau qui se situe entre le côté maître (sous le contrôle de l'émulateur) et le côté esclave (avec lequel interagissent les applications exécutées dans le terminal)).
Une commande pour configurer cette discipline de ligne tty est la stty
commande.
Lorsque vous exécutez une application stupide comme cat
celle-ci ne sait pas et ne se soucie pas de savoir si son stdin est un terminal ou non, le terminal est dans un mode canonique par défaut où la discipline de ligne tty implémente un éditeur de ligne brut .
Certaines applications interactives qui ont besoin de plus que cet éditeur de ligne brut modifient généralement ces paramètres au démarrage et les restaurent à la sortie. Les obus modernes, à leur demande, sont des exemples de telles applications. Ils implémentent leur propre éditeur de ligne plus avancé.
En règle générale, lorsque vous entrez dans une ligne de commande, le shell place la discipline de ligne tty dans ce mode, et lorsque vous appuyez sur Entrée pour exécuter la commande en cours, le shell restaure le mode tty normal (comme c'était le cas avant d'émettre l'invite).
Si vous exécutez la stty -a
commande, vous verrez les paramètres actuels utilisés pour les applications stupides . Vous êtes susceptible de voir icanon
, echo
et les echoctl
paramètres sont activés.
Cela signifie que:
icanon
: cet éditeur de ligne brute est activé.
echo
: les caractères que vous saisissez (que l'émulateur de terminal écrit sur le côté maître) sont renvoyés en écho (mis à disposition pour lecture par l'émulateur de terminal).
echoctl
: au lieu d'être répercutés asis, les caractères de contrôle sont répercutés comme ^X
.
Alors, disons que vous tapez A B Backspace-aka-Ctrl+H/? C Ctrl+X Backspace Return.
Votre émulateur de terminal envoie: AB\bC\x18\b\r
. La discipline de ligne fera écho : AB\b \bC^X\b \b\b \b\r\n
et une application qui lit l'entrée du côté esclave ( /dev/pts/x
) lira AC\n
.
Tout ce que l'application voit est AC\n
, et uniquement lorsque votre presse Enterne peut donc avoir aucun contrôle sur la sortie ^X
.
Vous remarquerez que pour l' écho , le premier ^H
( ^?
avec certains terminaux, voir le erase
réglage) a abouti à \b \b
être renvoyé au terminal. C'est la séquence pour déplacer le curseur en arrière, écraser avec de l'espace, déplacer à nouveau le curseur, tandis que la seconde ^H
a \b \b\b \b
pour effet d'effacer ces deux caractères ^
et X
.
Le ^X
(0x18) lui-même était en cours de traduction vers ^
et X
pour la sortie. Comme B
, il ne s'est pas rendu à l'application, car nous l'avons supprimé avec Backspace.
\r
(aka ^M
) a été traduit en \r\n
( ^M^J
) pour l'écho et \n
( ^J
) pour l'application.
Alors, quelles sont nos options pour ces applications stupides :
- désactiver
echo
( stty -echo
). Cela change efficacement la façon dont les personnages de contrôle sont répercutés, en ... ne faisant rien en écho. Pas vraiment une solution.
- désactiver
echoctl
. Cela change la façon dont les caractères de contrôle (autres que ^H
, ^M
... et tous les autres utilisés par l'éditeur de ligne) sont répercutés. Ils sont ensuite répercutés tels quels . Autrement dit, le caractère ESC est envoyé comme l' octet \e
( ^[
/ 0x1b
) (qui est reconnu comme le début d'une séquence d'échappement par le terminal), ^G
vous envoyez un \a
(un BEL, faisant bip de votre terminal) ... Pas une option .
- désactiver l'éditeur de ligne brute (
stty -icanon
). Pas vraiment une option car les applications brutes deviendraient beaucoup moins utilisables.
- éditez le code du noyau pour changer le comportement de la discipline de ligne tty afin que l' écho d'un caractère de contrôle envoie
\e[7m^X\e[m
au lieu de juste ^X
(ici, \e[7m
permet généralement la vidéo inversée dans la plupart des terminaux).
Une option pourrait être d'utiliser un wrapper comme rlwrap
celui-ci est un hack sale pour ajouter un éditeur de ligne sophistiqué aux applications stupides. Ce wrapper essaie en fait de remplacer les simples read()
s du terminal par des appels à l'éditeur de ligne readline (qui modifient le mode de la discipline de ligne tty).
Pour aller encore plus loin, vous pouvez même essayer des solutions comme celle-ci qui détourne toutes les entrées du terminal pour passer par l'éditeur de ligne de zsh (qui se trouve mettre en surbrillance ^X
s en vidéo inverse) en s'appuyant sur la :exec
fonctionnalité de l'écran GNU .
Maintenant, pour les applications qui implémentent leur propre éditeur de ligne, c'est à eux de décider comment l' écho est fait. bash
utilise readline pour ce qui ne prend pas en charge la personnalisation de l'écho des caractères de contrôle.
Pour zsh
, voir:
info --index-search='highlighting, special characters' zsh
zsh
met en surbrillance les caractères non imprimables par défaut. Vous pouvez personnaliser la mise en évidence avec par exemple:
zle_highlight=(special:fg=white,bg=red)
Pour surligner le blanc sur le rouge pour ces caractères spéciaux.
La représentation textuelle de ces caractères n'est cependant pas personnalisable.
Dans un lieu UTF-8, 0x18 sera rendu comme ^X
, \u378
, \U7fffffff
(deux points de code unicode non affectés) comme <0378>
, <7FFFFFFF>
, \u200b
(un caractère unicode non vraiment imprimable) comme <200B>
.
\x80
dans une locale iso8859-1 serait rendu comme ^�
... etc.
bash
ilreadline
gère ce genre de choses, et pour la plupart des autres, c'est le pilote tty.