Jak działa komenda Clear?


33

Niedawno próbowałem dowiedzieć się więcej o tym, jak działa powłoka i patrzyłem, jak cleardziała polecenie. Plik wykonywalny znajduje się w /usr/bin/clearnim i wydaje się, że wypisuje kilka pustych linii (równych wysokości terminala) i umieszcza kursor w lewym górnym rogu terminala.

Dane wyjściowe polecenia są zawsze takie same, niezależnie od wielkości terminala:

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

i może być replikowany za pomocą echa mającego dokładnie taki sam efekt:

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

Byłem naprawdę ciekawy, jak to wyjście tego polecenia przekłada się na wyczyszczenie konsoli.


CTRL + L - spójrz nastty -a
mikeserv

Odpowiedzi:


26

Dane wyjściowe clearpolecenia to kody specjalne konsoli. Dokładne wymagane kody zależą od używanego terminala, jednak większość używa sekwencji sterujących ANSI. Oto dobry link wyjaśniający różne kody - http://www.termsys.demon.co.uk/vtansi.htm . Odpowiednie fragmenty to:

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.

I:

Erase Screen        <ESC>[2J

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

Gdzie <ESC>jest szesnastkowy 1Blub ósemkowy 033. Innym sposobem wyświetlania znaków jest:

clear | sed -n l

18

Działa poprzez wydawanie pewnych sekwencji ucieczki ANSI . W szczególności te dwa:

Esc [Linia; KolumnaH Pozycja kursora:
Esc [Linia; Kolumna] Przesuwa kursor do określonej pozycji (współrzędne). Jeśli nie
                                         określisz pozycji, kursor przesunie się do pozycji początkowej w lewym górnym
                                         rogu ekranu (linia 0, kolumna 0).

Esc [2J Erase Display:
                                         Czyści ekran i przesuwa kursor do pozycji początkowej
                                         (linia 0, kolumna 0).

Być może łatwiej to zrozumieć w wyniku od -c:

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

033Jest Esc, więc wyjście powyżej jest po prostu Esc[Ha następnie Esc[2J.


9

Dane wyjściowe wysyłane przez clear (1) zależą od typu terminala, zdefiniowanego przez $ TERM w środowisku powłoki. Robi to samo, co polecenie „tput clear”, które wyszukuje kod zmiany znaczenia dla bieżącego typu terminala i wysyła ten ciąg na standardowe wyjście.

Terminal odbierający kod ucieczki od clear / tput interpretuje go i wykonuje wysłane polecenie, takie jak wyczyszczenie lokalnego wyświetlacza. „terminal” oznacza konsolę lokalną lub sesję terminala (putty, xterm itp.), ewentualnie za pośrednictwem ssh lub telnet.


7

Dziwi mnie, że inne odpowiedzi nie wspominały o TERMINFO (lub TERMCAP)

Skorzystaj ze stron podręcznika Luke

man clear mówi ...

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.

SEMESTR

clearKomenda używa tylko ANSI sekwencje jeśli $TERMjest ustawiony na ANSI lub ANSI opartej pewnego rodzaju terminali jak 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

Możesz użyć infocmpdo zbadania

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

TPUT

Lub możesz użyć, tputaby wyświetlić zdolność

$ 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

Oprócz wszystkich fajnych odpowiedzi powyżej, możemy zrobić trochę wysiłku, aby zobaczyć, co się stanie:

$ 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

Widzisz, dwa polecenia zapewniają to samo ANSI escape sequences.


0

Po pierwsze / bin / echo -e "\ x1b \ x5b \ x48 \ x1b \ x5b \ x32 \ x4a \ c" tak naprawdę nie czyści ekranu. Możesz przewinąć w górę, aby zobaczyć poprzednią zawartość.

Po drugie, otworzyłem IRB (który jest interaktywną powłoką Ruby) i napisałem:

p `clear`

Lub

p %x(clear)

Lub:

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

Wszystkie kody powinny zostać zwrócone "\e[3J\e[H\e[2J"

Teraz otwórz terminal, wpisz echo -e "\e[3J\e[H\e[2J"

Powinien wyczyścić ekran. Są to tak zwane sekwencje specjalne ANSI:

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

Możesz użyć tych kodów do mrugnięcia tekstu ( \e[5m), pokolorowania tekstu: ( for i in {0..255} ; do printf "\e[38;5;${i}m${i} " ; done ; echo) i wielu innych rzeczy!

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.