Como o comando claro funciona?

30

Recentemente, eu estava tentando aprender mais sobre como o shell funciona e estava analisando como o comando clear funciona. O executável está localizado em /usr/bin/clear e parece imprimir um monte de linhas em branco (igual à altura do terminal) e coloca o cursor na parte superior esquerda do terminal.

A saída do comando é sempre a mesma, independentemente do tamanho do terminal:

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

e pode ser replicado com o eco tendo exatamente o mesmo efeito:

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

Eu estava realmente curioso em saber como essa saída desse comando se traduz em limpar o console.

    
por Eric 14.04.2014 / 21:17

5 respostas

25

A saída do comando clear é códigos de escape do console. Os códigos exatos necessários dependem do terminal exato que você está usando, no entanto, a maioria usa seqüências de controle ANSI. Aqui está um bom link explicando os vários códigos - link . Os snippets relevantes são:

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.

E:

Erase Screen        <ESC>[2J

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

Em que <ESC> é hexadecimal 1B ou octal 033 . Outra maneira de ver os personagens é com:

clear | sed -n l
    
por 14.04.2014 / 21:44
17

Funciona emitindo certas sequências de escape ANSI . Especificamente, estes dois:

Esc[Line;ColumnH          Cursor Position:
Esc[Line;Columnf            Moves the cursor to the specified position (coordinates). If you do not
                                         specify a position, the cursor moves to the home position at the upper-left
                                         corner of the screen (line 0, column 0).

Esc[2J                              Erase Display:
                                         Clears the screen and moves the cursor to the home position
                                         (line 0, column 0).

Isso talvez seja mais fácil de entender na saída de od -c :

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

033 é Esc , portanto, a saída acima é simplesmente Esc[H e, em seguida, Esc[2J .

    
por 14.04.2014 / 21:44
9

A saída enviada por clear (1) depende do seu tipo de terminal, definido por $ TERM no ambiente do shell. Ele faz a mesma coisa que o comando "tput clear", que está procurando o código de escape para o tipo de terminal atual e enviando essa string para a saída padrão.

O terminal que recebe o código de escape de clear / tput o interpreta e executa o comando enviado, como limpar a exibição local. "terminal" significa o console local ou uma sessão de terminal (putty, xterm, etc.), possivelmente via ssh ou telnet.

    
por 14.04.2014 / 21:45
6

Além de toda boa resposta acima, podemos fazer um pouco para ver o que acontece:

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

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

Você pode ver que dois comandos fornecem o mesmo ANSI escape sequences .

    
por 14.04.2014 / 21:51
6

Estou surpreso que outras respostas não tenham mencionado TERMINFO (ou TERMCAP)

Use as man pages Luke

man clear diz ...

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.

TERM

O comando clear usa apenas sequências de escape ANSI se o seu $TERM estiver definido como ANSI ou algum tipo de terminal baseado em ANSI, como 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

Você pode usar infocmp para investigar

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

TPUT

Ou você pode usar tput para ver uma capacidade

$ 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
    
por 16.04.2014 / 11:48