Як працює чітка команда?


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

18

Він працює, видаючи певні послідовності відбору ANSI . Зокрема, ці два:

Esc [Рядок; СтовпецьH Позиція курсору:
Esc [Лінія; 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", яка шукає код евакуації для поточного типу терміналу і надсилає цю рядок до стандартного виводу.

Термінал, який отримує код евакуації від clear / tput, інтерпретує його і виконує надіслану команду, таку як очищення локального дисплея. "термінал" означає локальну консоль або термінальний сеанс (putty, xterm тощо), можливо, через ssh або telnet.


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Команда використовує тільки 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 -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

На додаток до всієї приємної відповіді, описаної вище, ми можемо зробити деякі труднощі, щоб побачити, що відбувається:

$ 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.


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"

Це повинно очистити екран. Вони називаються 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) та багато іншого!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.