Comment fonctionne la commande claire?


33

J'essayais récemment d'en savoir plus sur le fonctionnement du shell et sur le fonctionnement de la clearcommande. L'exécutable est situé dans /usr/bin/clearet il semble imprimer un tas de lignes vierges (égales à la hauteur du terminal) et place le curseur en haut à gauche du terminal.

La sortie de la commande est toujours la même, quelle que soit la taille du terminal:

$ clear | hexdump -C
00000000  1b 5b 48 1b 5b 32 4a                              |.[H.[2J|
00000007

et peut être reproduit avec l’écho ayant exactement le même effet:

$ /bin/echo -e "\x1b\x5b\x48\x1b\x5b\x32\x4a\c"

J'étais vraiment curieux de savoir comment cette sortie de cette commande se traduisait par un effacement de la console.


CTRL + L - regardezstty -a
mikeserv le

Réponses:


26

Le résultat de la clearcommande est les codes d’échappement de la console. Les codes exacts requis dépendent du terminal que vous utilisez, mais la plupart utilise des séquences de contrôle ANSI. Voici un bon lien expliquant les différents codes - http://www.termsys.demon.co.uk/vtansi.htm . Les extraits pertinents sont:

Cursor Home         <ESC>[{ROW};{COLUMN}H

Sets the cursor position where subsequent text will begin. If no row/column
parameters are provided (ie. <ESC>[H), the cursor will move to the home position,
at the upper left of the screen.

Et:

Erase Screen        <ESC>[2J

Erases the screen with the background colour and moves the cursor to home.

<ESC>est hex 1Bou octal 033. Une autre façon de voir les personnages est avec:

clear | sed -n l

18

Cela fonctionne en émettant certaines séquences d'échappement ANSI . Plus précisément, ces deux:

Esc [Ligne; ColonneH Position du curseur:
Esc [Ligne; Colonnef Déplace le curseur à la position spécifiée (coordonnées). Si vous ne
                                         spécifiez pas de position, le curseur se déplace sur la position d'origine dans le coin supérieur gauche
                                         de l'écran (ligne 0, colonne 0).

Esc [2J Erase Display:
                                         efface l'écran et déplace le curseur sur la position d'origine
                                         (ligne 0, colonne 0).

C’est peut-être plus facile à comprendre dans le résultat de od -c:

$ clear | od -c
0000000 033   [   H 033   [   2   J
0000007

033est Esc, donc la sortie ci-dessus est simplement Esc[Het alors Esc[2J.


9

La sortie envoyée par clear (1) dépend de votre type de terminal, défini par $ TERM dans l'environnement shell. Il fait la même chose que la commande "tput clear", qui recherche le code d'échappement du type de terminal actuel et envoie cette chaîne à la sortie standard.

Le terminal recevant le code d'échappement de clear / tput l'interprète et exécute la commande envoyée, telle que l'effacement de l'affichage local. "terminal" signifie la console locale ou une session de terminal (putty, xterm, etc.), éventuellement via ssh ou telnet.


7

Je suis surpris que d'autres réponses n'aient pas mentionné TERMINFO (ou TERMCAP)

Utilisez les pages de manuel de Luke

man clear dit ...

NAME
       clear - clear the terminal screen

SYNOPSIS
       clear

DESCRIPTION
       clear clears your screen if this is possible.  It looks in the environ-
       ment for the terminal type and then in the terminfo database to  figure
       out how to clear the screen.

TERME

La clearcommande utilise uniquement les séquences d'échappement ANSI si votre $TERMest défini sur ANSI ou sur un type de terminal basé sur ANSI tel que XTERM.

$ TERM=ansi clear | hexdump -C
00000000  1b 5b 48 1b 5b 4a                                 |.[H.[J|
00000006

$ TERM=wy50 clear | hexdump -C
00000000  1b 2b                                             |.+|
00000002

$ TERM=hurd clear | hexdump -C
00000000  1b 63                                             |.c|
00000002

$ TERM=glasstty clear | hexdump -C
00000000  0c                                                |.|
00000001

$ TERM=vt52 clear | hexdump -C
00000000  1b 48 1b 4a                                       |.H.J|
00000004

$ TERM=hpterm clear | hexdump -C
00000000  1b 26 61 30 79 30 43 1b  4a                       |.&a0y0C.J|
00000009

INFOCMP

Vous pouvez utiliser infocmppour enquêter

$ infocmp -L -1 hpterm | grep clear_screen
        clear_screen=\E&a0y0C\EJ,

TPUT

Ou vous pouvez utiliser tputpour afficher une capacité

$ tput -T hpterm clear | hexdump -C
00000000  1b 26 61 30 79 30 43 1b  4a                       |.&a0y0C.J|
00000009


$ tput -T hpterm reset | hexdump -C
00000000  20 20 20 20 20 20 20 20  1b 31 20 20 20 20 20 20  |        .1      |
00000010  20 20 1b 31 20 20 20 20  20 20 20 20 1b 31 20 20  |  .1        .1  |
00000020  20 20 20 20 20 20 1b 31  20 20 20 20 20 20 20 20  |      .1        |
00000030  1b 31 20 20 20 20 20 20  20 20 1b 31 20 20 20 20  |.1        .1    |
00000040  20 20 20 20 1b 31 20 20  20 20 20 20 20 20 1b 31  |    .1        .1|
00000050  20 20 20 20 20 20 20 20  1b 31 20 20 20 20 20 20  |        .1      |
00000060  20 20 1b 31                                       |  .1|
00000064

6

En plus de toutes les bonnes réponses ci-dessus, nous pouvons faire quelques efforts pour voir ce qui se passe:

$ strace -e trace=write echo -e "\x1b\x5b\x48\x1b\x5b\x32\x4a\c"
write(1, "\33[H\33[2J", 7

$ strace -e trace=write clear
write(1, "\33[H\33[2J", 7

Vous pouvez voir que deux commandes fournissent la même chose ANSI escape sequences.


0

Premièrement, / bin / echo -e "\ x1b \ x5b \ x48 \ x1b \ x5b \ x32 \ x4a \ c" n'efface pas vraiment l'écran. Vous pouvez faire défiler vers le haut pour voir le contenu précédent.

Deuxièmement, j'ai ouvert IRB (qui est un shell Ruby interactif) et tapé:

p `clear`

Ou

p %x(clear)

Ou:

require 'open3'
p Open3.capture2('clear')[0]

Tous les codes doivent retourner "\e[3J\e[H\e[2J"

Maintenant, ouvrez votre terminal, tapez echo -e "\e[3J\e[H\e[2J"

Il devrait effacer l'écran. Celles-ci sont appelées séquences d'échappement ANSI:

https://en.wikipedia.org/wiki/ANSI_escape_code

Vous pouvez utiliser ces codes pour faire clignoter un texte ( \e[5m), coloriser un texte: ( for i in {0..255} ; do printf "\e[38;5;${i}m${i} " ; done ; echo) et bien d'autres choses!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.