我们今天来聊一聊linux下的命令行以及它的颜色。命令行除了它朴素的黑白色调外还有绚丽多彩的一面。
自定义bash脚本 colors.sh 的输出
命令行 colortest-8 的输出
命令行 colortest-16b 的输出
命令行 colortest-256 的输出
上述色块,除了第一个是自定义脚本外,其它几个都是系统包 colortest 自带的脚本。
从上图可以看到,命令行实际上是可以被搞出非常花的调调的,只是大家以黑为美,当需要点缀时才给一点颜色See See。
我们平时提到的终端 tty、Console、Terminal,不加区分的话可以认为是同一类事物。还是要区分一下终端、仿终端 tty 与伪终端 pts 的概念,这里涉及到用于显示的硬件的发展的历史。
我们一起来复习一下IT历史,我们是1949年建国,日本是1945年投降的,真正能看的电视是日本sony公司在战后1950年代搞出来的。战后的日本在美国的扶持下,半导体蓬勃发展,sony造出了世界上第一台晶体管电视8-301,到1960年代,晶体管CRT电视开始出现,1996年,sony搞出来第一款纯平CRT,而直到1998 LCD液显示器才开始出现。1983年版的射雕大家印象比较深刻,但在1982年2月英特尔的80286才面世,再到1991年Linux才诞生,发生这些大事的时候,国内还在流行黑白电视转彩电,而小朋友们则还在玩小霸王其乐无穷和街机游戏。
有了电视才慢慢演化出后来的显示器。1958年英特尔搞出集成电路,1976年英特尔又推出它的16位处理器8086。在这个过程中,日本跟在美国后面开始造电视,造内存,狂点半导体技能点,直到川总上台后我国才醒悟芯片还是要自己人搞,而这几乎是一代人的断层。要搞芯片还是要看00后这代人如何追赶。毕竟人的前20年都是懵懂的少年基本没有什么创造力,20到35岁人的精力最旺盛,过了35岁,老婆、孩子、热炕头,搞IT的都被赶回家了,现在过了35岁连事业单位都不要了。回到终端话题,早期的计算机是没有显示器可用的。
那在电视、显示器进化到能用的程度之前,什么最流行?当然是广播啦。无线电通讯在二战时被用到了极致,民用是广播、军用就是电报。电报加打字机就是所谓的电传打字机(teletype)。Linux中的终端tty就是指的电传打字机(teletype),它是早期的计算机的主要终端。
计算机专业的肯定听说过早期的计算机的输入是在纸带上打洞,早期的计算机的输出实际上也是打洞。只不过这些纸带的洞可以作为电报信息发出去,电报信息经电传打字机自动解码就可以直接把英文字母在滚筒纸上打印出来。所以早期的打字机和计算机是这种特殊的合作模式。而电报作为军用级武器,分别在作战的两地配上两台电传打字机,就可以达到隔空聊QQ的效果,速度在1分钟可以打印40多个字母,比人工翻译电报快多了。现代的键盘就是从打字机(Typewriter)上照搬过来的,以前的机械式打字机长这个样子:
这也是为什么我们说终端设备即是输入设备又是输出设备,因为它们是一体的,即有键盘的作用,又有显示的作用(打在纸上显示)。后期的仿终端比如串口,即可以作输入,又可以作输出。
后期计算机终端变了样,但作为早期终端的电传打字机(teletype)tty 被保留了下来。Linux下tty1-tty6分别代表了6个模拟的字符终端,方便我们在受限的条件下开多个窗口,tty7代表图形终端。在原生Linux环境,Ctrl + Alt + Fn 可以在tty1-tty7间切换,除了可以用快捷键切换,还可以使用命令 chvt n 切换,而内核的输出一般会输出到tty1上,有时我们到机房去检查服务器是否挂掉,可以在显示器终端上看到kernel panic的信息,内核有权限操作物理硬件,tty1-6可以理解为工作在内核模式,它代表的是硬件。这些内核输出信息在伪终端上是不会显示的。那什么是伪终端,伪终端与 tty 有什么关系呢?
Linux的命令行界面的终端分两类,一种是内核态的仿终端,还有一类是用户态的伪终端。其中仿终端是真实的物理设备,比如串口、显示器VGA接口等,内核的报错输出会输出到仿终端上。为什么叫仿终端?因为真的终端(tty)在现实生活中已经不存在了,比如显示器还没发明时使用的电传打字机,后来的串口、VGA接口都是仿真之前的终端,所以叫仿终端。 而伪终端(pseudo terminal 或 pty)是通过软件实现的,它们已经脱离硬件的范畴,只是看起来像终端而已,当内核出问题时这些上层建筑都会不好使。因为硬件终端数据有限,比如嵌入式板子上就只有一个串口,连显示器VGA口都没有,要对硬件操作只能通过串口用于显示或输入。只有串口时,串口就是tty,有VGA显示器时,VGA就是默认的tty。而我们通过ssh连接的都是伪终端pty。
在Linux下输入tty,可以查看当前的终端号:
root@ns-xxzx-svr:~# tty
/dev/pts/1
复制
终端的颜色输出是由特殊字符进行装饰的,比如文本文件
^[[32m《感遇 其一》^[[m
^[[33m作者:张九龄^[[m
兰叶春葳蕤,桂华秋皎洁。
欣欣此生意,自尔为佳节。
谁知林栖者,闻风坐相悦。
草木有本心,何求美人折?
复制
通过cat查看,输出到终端上就显示成下面这个样子:
文本文件中的特殊标记就是Linux终端中的颜色标记。通过特殊标记进行包裹的文本,在Linux下输出时会被终端程序着色。
我们看一段关于终端颜色的教学脚本 colors.sh
printf " "
for b in 0 1 2 3 4 5 6 7; do printf " 4${b}m "; done
echo
for f in "" 30 31 32 33 34 35 36 37; do
for s in "" "1;"; do
printf "%4sm" "${s}${f}"
printf " \033[%sm%s\033[0m" "$s$f" "gYw "
for b in 0 1 2 3 4 5 6 7; do
printf " \033[4%s;%sm%s\033[0m" "$b" "$s$f" " gYw "
done
echo
done
done
复制
横排的 40m - 47m 代表了 背景色
纵排的 30m - 37m 代表了 前景色
0m 代表重置颜色设置,一般用来锚定色块的结束部分。
\033[ 用来锚定颜色代码的起始,其中 \033 可以用 \e 代替。这些字符是转义字符,也就是说是不可见的字符,我们通过 echo -e 将转义字符输出看一下效果。
当前只设置了前景色,如果需要即设置前景色又设置背景色,可以使用两次颜色标记,顺序可以颠倒。\e[35m 代表字体颜色,\e[47m代表背景,\e[0m代表结束,把颜色设置还原,不然后续所有命令都会被着色,相当于改了整个屏幕的颜色设置。
通过对照色表,即可输出自己想要的颜色。转义字符重定向到文件中之后,\e或\033会变化,\e 经echo -e 转义之后变成^[
对于带颜色的输出,可以通过sed去色转化为纯文本。
sed 去色命令为:
sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
复制