Как работает команда очистки?

33

Недавно я пытался узнать больше о том, как работает оболочка, и смотрел, как clearработает команда. Исполняемый файл находится внутри, /usr/bin/clearи, кажется, он выводит несколько пустых строк (равных высоте терминала) и помещает курсор в верхний левый угол терминала.

Вывод команды всегда один и тот же, независимо от размера терминала:

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

и может быть воспроизведено с эхом, имеющим точно такой же эффект:

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

Мне было действительно любопытно, как этот вывод этой команды переводит на очистку консоли.

Эрик
источник
CTRL + L - посмотреть наstty -a
mikeserv

Ответы:

26

Выходные данные clearкоманды - управляющие коды консоли. Точные требуемые коды зависят от того, какой именно терминал вы используете, однако в большинстве случаев используются последовательности управления ANSI. Вот хорошая ссылка, объясняющая различные коды - http://www.termsys.demon.co.uk/vtansi.htm . Соответствующие фрагменты:

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.

А также:

Erase Screen        <ESC>[2J

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

Где <ESC>шестнадцатеричный 1Bили восьмеричный 033. Еще один способ просмотра символов:

clear | sed -n l
Graeme
источник
18

Это работает, выпуская определенные escape-последовательности ANSI . В частности, эти два:

Esc [Line; ColumnH Cursor Position:
Esc [Line; Columnf Перемещает курсор в указанную позицию (координаты). Если вы не
                                         укажете позицию, курсор переместится в исходное положение в верхнем левом
                                         углу экрана (строка 0, столбец 0).

Esc [2J Erase Display:
                                         очищает экран и перемещает курсор в исходное положение
                                         (строка 0, столбец 0).

Возможно, это легче понять в выводе od -c:

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

033есть Esc, так что вывод выше просто Esc[Hи потом Esc[2J.

Тердон
источник
9

Вывод, передаваемый clear (1), зависит от типа вашего терминала, определенного $ TERM в среде оболочки. Он делает то же самое, что и команда «tput clear», которая ищет код выхода для текущего типа терминала и отправляет эту строку в стандартный вывод.

Терминал, получающий код escape от clear / tput, интерпретирует его и выполняет отправленную команду, например, очищает локальный дисплей. «терминал» означает локальную консоль или сеанс терминала (putty, xterm и т. д.), возможно, через ssh или telnet.

mlgoth
источник
7

Я удивлен, что другие ответы не упомянули TERMINFO (или TERMCAP)

Используйте справочные страницы Люка

man clear говорит ...

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.

СРОК

Команда clearиспользует escape-последовательности ANSI только в том случае, если $TERMзадано ANSI или какой-либо тип терминала на основе ANSI, например 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

Вы можете использовать infocmpдля расследования

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

TPUT

Или вы можете использовать tputдля просмотра возможностей

$ 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
RedGrittyBrick
источник
6

В дополнение ко всему хорошему ответу выше, мы можем сделать несколько шагов, чтобы увидеть, что произойдет:

$ 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

Как видите, две команды предоставляют одно и то же ANSI escape sequences.

cuonglm
источник
0

Во-первых, / bin / echo -e "\ x1b \ x5b \ x48 \ x1b \ x5b \ x32 \ x4a \ c" на самом деле не очищает экран. Вы можете прокрутить вверх, чтобы увидеть предыдущее содержимое.

Во-вторых, я открыл IRB (интерактивную оболочку Ruby) и набрал:

p `clear`

Или

p %x(clear)

Или:

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

Все коды должны вернуться "\e[3J\e[H\e[2J"

Теперь откройте свой терминал, введите echo -e "\e[3J\e[H\e[2J"

Это должно очистить экран. Это так называемые escape-последовательности ANSI:

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

Вы можете использовать эти коды, чтобы мигать текст ( \e[5m), окрасить текст: ( for i in {0..255} ; do printf "\e[38;5;${i}m${i} " ; done ; echo) и многое другое!

S.Goswami
источник