Làm thế nào để lệnh rõ ràng làm việc?


33

Gần đây tôi đã cố gắng tìm hiểu thêm về cách thức hoạt động của shell và xem xét cách thức clearhoạt động của lệnh. Tập tin thực thi được đặt trong /usr/bin/clearvà dường như in ra một loạt các dòng trống (bằng với chiều cao của thiết bị đầu cuối) và đặt con trỏ ở phía trên bên trái của thiết bị đầu cuối.

Đầu ra của lệnh luôn giống nhau, bất kể kích thước của thiết bị đầu cuối:

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

và có thể được nhân rộng với tiếng vang có tác dụng chính xác như sau:

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

Tôi thực sự tò mò làm thế nào đầu ra của lệnh này chuyển sang xóa giao diện điều khiển.


CTRL + L - nhìn vàostty -a
mikeerv

Câu trả lời:


26

Đầu ra của clearlệnh là mã thoát console. Các mã chính xác được yêu cầu phụ thuộc vào thiết bị đầu cuối chính xác mà bạn đang sử dụng, tuy nhiên hầu hết sử dụng các chuỗi điều khiển ANSI. Đây là một liên kết tốt giải thích các mã khác nhau - http://www.termsys.demon.co.uk/vtansi.htm . Các đoạn có liên quan là:

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.

Và:

Erase Screen        <ESC>[2J

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

Trường hợp <ESC>là hex 1Bhoặc bát phân 033. Một cách khác để xem các nhân vật là:

clear | sed -n l

18

Nó hoạt động bằng cách phát hành các chuỗi thoát ANSI nhất định . Cụ thể, hai:

Esc [Line; CộtH Vị trí con trỏ:
Esc [Line; Cộtf Di chuyển con trỏ đến vị trí (tọa độ) đã chỉ định. Nếu bạn không
                                         chỉ định một vị trí, con trỏ sẽ di chuyển đến vị trí nhà ở góc trên bên trái
                                         của màn hình (dòng 0, cột 0).

Esc [Hiển thị xóa 2J:
                                         Xóa màn hình và di chuyển con trỏ đến vị trí ban đầu
                                         (dòng 0, cột 0).

Điều này có lẽ dễ hiểu hơn trong đầu ra của od -c:

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

033Esc, vì vậy đầu ra ở trên chỉ đơn giản là Esc[Hsau đó Esc[2J.


9

Đầu ra được gửi bởi Clear (1) tùy thuộc vào loại thiết bị đầu cuối của bạn, được xác định bởi $ TERM trong môi trường shell. Nó thực hiện tương tự như lệnh "tput Clear", đang tìm mã thoát cho loại thiết bị đầu cuối hiện tại và gửi chuỗi đó đến đầu ra tiêu chuẩn.

Thiết bị đầu cuối nhận mã thoát từ Clear / tput diễn giải nó và thực thi lệnh được gửi, chẳng hạn như xóa màn hình cục bộ. "thiết bị đầu cuối" có nghĩa là bảng điều khiển cục bộ hoặc phiên cuối (putty, xterm, v.v.), có thể thông qua ssh hoặc telnet.


7

Tôi ngạc nhiên khi các câu trả lời khác không đề cập đến TERMINFO (hoặc TERMCAP)

Sử dụng trang người đàn ông Luke

man clear nói ...

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.

KỲ HẠN

Các clearlệnh chỉ sử dụng ANSI thoát khỏi chuỗi nếu bạn $TERMđược thiết lập để ANSI hoặc một số ANSI dựa trên loại thiết bị đầu cuối như 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

Bạn có thể sử dụng infocmpđể điều tra

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

TPUT

Hoặc bạn có thể sử dụng tputđể xem khả năng

$ 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

Ngoài tất cả các câu trả lời hay ở trên, chúng ta có thể thực hiện một số bước để xem điều gì xảy ra:

$ 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

Bạn có thể thấy, hai lệnh cung cấp giống nhau ANSI escape sequences.


0

Thứ nhất / bin / echo -e "\ x1b \ x5b \ x48 \ x1b \ x5b \ x32 \ x4a \ c" không thực sự xóa màn hình. Bạn có thể cuộn lên để xem nội dung trước đó.

Thứ hai, tôi đã mở IRB (là một vỏ Ruby tương tác) và gõ:

p `clear`

Hoặc là

p %x(clear)

Hoặc là:

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

Tất cả các mã sẽ trở lại "\e[3J\e[H\e[2J"

Bây giờ hãy mở terminal của bạn, gõ echo -e "\e[3J\e[H\e[2J"

Nó sẽ xóa màn hình. Chúng được gọi là các chuỗi thoát ANSI:

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

Bạn có thể sử dụng các mã này để nhấp nháy một văn bản ( \e[5m), viết một văn bản: ( for i in {0..255} ; do printf "\e[38;5;${i}m${i} " ; done ; echo) và nhiều thứ khác!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.