Lorsque vous tapez des caractères de contrôle dans le shell, ils s'affichent en utilisant ce qu'on appelle la "notation caret". Escape, par exemple, est écrit sous la forme ^[
en notation caret.
J'aime personnaliser mon shell bash pour le rendre cool. J'ai par exemple changé ma PS1
et PS2
devenir colorisé. Je veux maintenant que les personnages de contrôle aient également une apparence unique pour les distinguer davantage des personnages normaux.
$ # Here I type CTRL-C to abort the command.
$ blahblah^C
^^ I want these two characters to be displayed differently
Existe-t-il un moyen de faire en sorte que mon shell mette en évidence les caractères de contrôle différemment ?
Est-il possible de les afficher en gras ou peut-être de les faire apparaître dans des couleurs différentes du texte normal ?
J'utilise bash shell ici mais je n'ai pas tagué la question avec bash
car il existe peut-être une solution qui s'applique à de nombreux shells différents.
Remarque que je ne sais pas à quel niveau la surbrillance des caractères de contrôle a lieu. J'ai d'abord pensé que c'était dans la coquille elle-même. Maintenant j'ai entendu dire que c'est readline qui contrôle la façon dont les caractères de contrôle sont dans des shells comme bash . Donc, la question est maintenant étiquetée avec readline
et je cherche toujours des réponses.
Réponse acceptée :
Lorsque vous appuyez sur Ctrl+X , votre émulateur de terminal écrit l'octet 0x18 du côté maître de la paire de pseudo-terminaux.
Ce qui se passe ensuite dépend de la façon dont 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 les applications s'exécutant dans le terminal interagissent)) est configuré. /P>
Une commande pour configurer cette discipline de ligne tty est le stty
commande.
Lors de l'exécution d'une application stupide comme cat
qui ne sait pas et ne se soucie pas de savoir si son stdin est un terminal ou non, le terminal est dans un défaut canonique mode 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 lignes grossier modifiez généralement ces paramètres au démarrage et restaurez-les à la sortie. Des coquillages 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 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 (tel qu'il était en vigueur avant l'émission de l'invite).
Si vous exécutez le stty -a
commande, vous verrez les paramètres actuellement utilisés pour les applications stupides . Vous verrez probablement l'icanon
, echo
et echoctl
paramètres activés.
Cela signifie que :
icanon
:cet éditeur de lignes brutes est activé.echo
:les caractères que vous tapez (que l'émulateur de terminal écrit côté maître) sont en écho back (mis à disposition pour lecture par l'émulateur de terminal).echoctl
:au lieu d'être en écho asis, les caractères de contrôle sont en écho comme^X
.
Donc, disons que vous tapez A B Retour arrière-aka-Ctrl+H/? C Ctrl+X Retour arrière Retour .
Votre émulateur de terminal enverra :ABbCx18br
. La discipline de ligne écho retour :ABb bC^Xb bb brn
, et une application qui lit l'entrée du côté esclave (/dev/pts/x
) lira ACn
.
Tout ce que l'application voit est ACn
, et uniquement lorsque vous appuyez sur Entrée donc il ne peut avoir aucun contrôle sur la sortie pour ^X
là.
Vous remarquerez que pour echo , le premier ^H
(^?
avec certains terminaux, voir le erase
paramètre) a donné b b
renvoyé au terminal. C'est la séquence pour déplacer le curseur vers l'arrière, écraser avec un espace, déplacer le curseur vers l'arrière, tandis que le second ^H
a donné b bb b
pour effacer ces deux ^
et X
caractères.
Le ^X
(0x18) lui-même était traduit en ^
et X
pour la sortie. Comme B
, il n'est pas arrivé dans l'application, car nous l'avons supprimé avec Backspace.
r
(alias ^M
) a été traduit en rn
(^M^J
) pour echo, et n
(^J
) pour l'application.
Alors, quelles sont nos options pour ces stupides applications :
- désactiver
echo
(stty -echo
). Cela change effectivement la façon dont les caractères de contrôle sont répercutés, en… ne faisant écho à rien. 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 repris en écho. Ils sont ensuite écho comme si. C'est-à-dire, par exemple, le caractère ESC est envoyé en tant quee
(^[
/0x1b
) octet (qui est reconnu comme le début d'une séquence d'échappement par le terminal),^G
vous envoyez una
(un BEL, faisant biper votre terminal)… Pas une option. - désactiver l'éditeur de lignes brutes (
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^Xe[m
au lieu de simplement^X
(icie[7m
active généralement la vidéo inverse dans la plupart des terminaux).
Une option pourrait être d'utiliser un wrapper comme rlwrap
c'est un sale hack pour ajouter un éditeur de ligne sophistiqué à des applications stupides. Ce wrapper essaie en fait de remplacer le simple read()
s du terminal aux appels vers l'éditeur de ligne readline (qui changent le mode de la discipline de ligne tty).
En allant 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 met en évidence ^X
s en vidéo inverse) en s'appuyant sur l'écran :exec
de GNU fonctionnalité.
Désormais, pour les applications qui implémentent leur propre éditeur de ligne, c'est à elles 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 surbrillance avec par exemple :
zle_highlight=(special:fg=white,bg=red)
Pour un surlignage blanc sur rouge pour ces caractères spéciaux.
La représentation textuelle de ces caractères n'est cependant pas personnalisable.
Dans une locale UTF-8, 0x18 sera rendu sous la forme ^X
, u378
, U7fffffff
(deux points de code Unicode non attribués) comme <0378>
, <7FFFFFFF>
, u200b
(un caractère unicode pas vraiment imprimable) comme <200B>
.
x80
dans une locale iso8859-1 serait rendu sous la forme ^�
… etc.