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 comme ^[
en notation caret.
J'aime personnaliser ma coque bash pour la rendre cool. J'ai par exemple changé mon PS1
et PS2
devenir colorisé. Je veux maintenant que les personnages de contrôle obtiennent une apparence unique afin de 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 surligne 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 marqué la question bash
car il existe peut-être une solution qui s'applique à de nombreux shells différents.
Notez 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 une ligne de lecture qui contrôle la façon dont les caractères de contrôle sont dans des coquilles comme bash . La question est donc désormais identifiée readline
et je cherche toujours des réponses.
bash
ilreadline
gère ce genre de choses, et pour la plupart des autres, c'est le pilote tty.vi
etless
mettent souvent en évidence les caractères de contrôle différemment du texte normal. Je vais modifier la question avec ces informations. Je vous remercie!zsh
ce qui le fait hors de la boîte.Réponses:
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 voiricanon
,echo
et lesechoctl
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
) liraAC\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 leerase
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^
etX
.Le
^X
(0x18) lui-même était en cours de traduction vers^
etX
pour la sortie. CommeB
, 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 :
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.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 .stty -icanon
). Pas vraiment une option car les applications brutes deviendraient beaucoup moins utilisables.\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 simplesread()
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:zsh
met en surbrillance les caractères non imprimables par défaut. Vous pouvez personnaliser la mise en évidence avec par exemple: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.la source
J'ai généralement ce code dans mon fichier .bashrc:
puis j'appelle cette fonction dans ma PS1
Avec cela, si vous appuyez sur ^ C, vous le verrez dans votre invite
Tous les codes d'état de sortie qui ne sont pas "0" seront invités.
la source