clear做了啥?
clear
做的工作很简单:把待输入的下一行移动到左上角。
所以你看,它根本没有真正对终端的内容进行清除,只不过是将其藏起来了。
如何实现clear
Linux的终端控制序列
Linux控制台实现了VT102和ECMA-48/ISO 6429/ANSI X3.64终端控制的子集,详见:console_codes - ubuntu man page。
Linux使用ANSI escape code方式来描述其控制序列,详见:ANSI escape code - Wikipedia。
简而言之,使用ESC
符号开始的一串字符序列会被解析成控制序列,多数控制序列由CSI(control sequence introducer)开始,由ESC [
来表示。
使用printf命令实现clear
printf
支持终端控制序列,其中ESC
可以用\e
转义符表示。
console_codes - ubuntu man page中给出了一个表(节选):
Sequences
Name
Describe
ESC @
ICH
Insert the indicated # of blank characters.
ESC A
CUU
Move cursor up the indicated # of rows.
ESC B
CUD
Move cursor down the indicated # of rows.
ESC C
CUF
Move cursor right the indicated # of columns.
ESC D
CUB
Move cursor left the indicated # of columns.
ESC E
CNL
Move cursor down the indicated # of rows, to column 1.
ESC F
CPL
Move cursor up the indicated # of rows, to column 1.
ESC G
CHA
Move cursor to indicated column in current row.
ESC H
CUP
Move cursor to the indicated row, column (origin at 1,1).
ESC J
ED
Erase display (default: from cursor to end of display).
ESC [ 1 J
erase from start to cursor.
ESC [ 2 J
erase whole display.
维基百科中ANSI escape code - Wikipedia中也说到:
CSI 2 J — This clears the screen and, on some devices, locates the cursor to the y,x position 1,1 (upper left corner).
CSI 2 J
或ESC [ 2 J
指令会在清除屏幕后将光标移动到第一行第一列(左上角)。
结合printf
,得出以下命令:
printf "\e[2J"
不知道是不是Linux水土的问题,这个命令执行效果和描述不太一样,其实际效果是将当前行顶出屏幕外(负一行),并打印若干空白行(尼玛)。
为了修正这个问题,我们看到有个指令ESC H
,描述如下:
Move cursor to the indicated row, column (origin at 1,1).
于是我们可以借助这个指令来完善我们的功能,修改如下:
printf "\e[H\e[2J"
这下终于完成我们
坑爹
的clear
命令。
难道就只是这样吗?
clear
命令这么坑爹Linus Torvalds知道吗?
实现一个真正意义上的clear
在console_codes - ubuntu man page中发现了另一个东西:
Sequences
Name
Describe
ESC c
RIS
Reset
重置你的终端来达到清除内容的效果。
printf "\ec"
真是一个简单又暴力的方法。
推荐写成shell脚本并移动到/usr/bin/目录下。
@LYC
转载请注明出处。