清除命令如何工作?

Eri*_*ric 36 shell terminal

我最近试图了解有关 shell 如何工作的更多信息,并正在研究该clear命令的工作原理。可执行文件位于,/usr/bin/clear它似乎打印出一堆空行(等于终端的高度)并将光标放在终端的左上角。

无论终端的大小如何,命令的输出始终相同:

$ clear | hexdump -C
00000000  1b 5b 48 1b 5b 32 4a                              |.[H.[2J|
00000007
Run Code Online (Sandbox Code Playgroud)

并且可以使用具有完全相同效果的回声进行复制:

$ /bin/echo -e "\x1b\x5b\x48\x1b\x5b\x32\x4a\c"
Run Code Online (Sandbox Code Playgroud)

我真的很好奇这个命令的输出是如何转换为清除控制台的。

Gra*_*eme 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.
Run Code Online (Sandbox Code Playgroud)

和:

Erase Screen        <ESC>[2J

Erases the screen with the background colour and moves the cursor to home.
Run Code Online (Sandbox Code Playgroud)

<ESC>十六进制1B或八进制在哪里033。查看字符的另一种方法是:

clear | sed -n l
Run Code Online (Sandbox Code Playgroud)


ter*_*don 19

它通过发出某些ANSI 转义序列来工作。具体来说,这两个:

Esc[Line;ColumnH 光标位置:
Esc[Line;Columnf 将光标移动到指定位置(坐标)。如果不
                                         指定位置,光标将移动到
                                         屏幕左上角的起始位置(第 0 行,第 0 列)。

Esc[2J 擦除显示:
                                         清除屏幕并将光标移动到起始位置
                                         (第 0 行,第 0 列)。

这在以下输出中可能更容易理解od -c

$ clear | od -c
0000000 033   [   H 033   [   2   J
0000007
Run Code Online (Sandbox Code Playgroud)

033Esc,所以上面的输出是简单的Esc[H然后Esc[2J


小智 9

clear(1) 发送的输出取决于您的终端类型,由 shell 环境中的 $TERM 定义。它与命令“tput clear”执行相同的操作,后者查找当前终端类型的转义码并将该字符串发送到标准输出。

从clear/tput接收到escape code的终端解释它并执行发送的命令,例如清除本地显示。“终端”是指本地控制台或终端会话(putty、xterm 等),可能通过 ssh 或 telnet。


Red*_*ick 7

我很惊讶其他答案没有提到 TERMINFO(或 TERMCAP)

使用手册页 Luke

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.
Run Code Online (Sandbox Code Playgroud)

学期

clear如果您$TERM设置为 ANSI 或某些基于 ANSI 的终端类型(例如 XTERM),则该命令仅使用 ANSI 转义序列。

$ 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
Run Code Online (Sandbox Code Playgroud)

信息管理计划

你可以infocmp用来调查

$ infocmp -L -1 hpterm | grep clear_screen
        clear_screen=\E&a0y0C\EJ,
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)


cuo*_*glm 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
Run Code Online (Sandbox Code Playgroud)

您可以看到,两个命令提供相同的ANSI escape sequences.