คำสั่งที่ชัดเจนทำงานอย่างไร


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คำสั่งคือ console escape codes รหัสที่แน่นอนจำเป็นต้องใช้ขึ้นอยู่กับเทอร์มินัลที่แน่นอนที่คุณกำลังใช้ แต่ส่วนใหญ่ใช้ลำดับการควบคุม 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 [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[HEsc[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เพื่อดูความสามารถ

$ 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 เพื่อดูว่าเกิดอะไรขึ้น:

$ 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 escape sequences:

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) และอื่น ๆ อีกมากมาย!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.