你的命令行是如何显示颜色的?浅谈我们每天都在使用但了解很少的TTY设备 您所在的位置:网站首页 智能配色软件原理 你的命令行是如何显示颜色的?浅谈我们每天都在使用但了解很少的TTY设备

你的命令行是如何显示颜色的?浅谈我们每天都在使用但了解很少的TTY设备

2023-03-14 23:28| 来源: 网络整理| 查看: 265

回想起初学编程时,我们只能在黑漆漆的命令行窗口中敲代码,Windows里面的CMD是刚开始学习编程的人的第一印象。

Visual Studio的hello world程序

随着技能提升,我们现在的编程工具已经发生了翻天覆地的变化。我们可以使用各种各样的终端软件来编写代码,这些终端软件不仅外观精美、使用方便,而且功能强大、效率高,让编程变得更加有趣和愉快。比如,像VS Code这样的IDE,让我们能够在一个集成化的开发环境中完成代码编辑、调试和测试等操作;还有像iTerm2这样的终端模拟器,提供了更丰富的终端功能和自定义选项,方便我们快速完成各种任务。更有oh-my-zsh这样的风靡全球的插件,第一眼就让人爱不释手。

oh-my-zsh结合iTerms2显示终端

第一次看到这样的界面,我不禁怀疑:这真的是命令行界面吗?

想要了解这一问题,就必须了解tty相关的内容。

关于tty的历史发展,请参看这篇文章:

简单来说,可以把tty看做程序与终端显示之间的桥梁:

当用户在终端上输入命令时,终端会将输入发送给TTY,TTY将其传递给相关的程序进行处理。程序可以向TTY发送输出,TTY将其转发到终端进行显示。TTY也负责处理控制字符和终端设置,例如光标移动、文本颜色和窗口大小等。

总之,TTY允许程序通过终端与用户交互,并在终端上显示输出。

有了这一基本概念之后,让我们来看看TTY能够实现哪些功能。

在终端显示颜色

终端颜色显示的标准是由ANSI定义的,具体可参见维基百科的相关页面。

本质上就是将要显示的颜色通过文字描述交给TTY。

大家可以试试以下命令:

echo -e '\e[31;46mxxxxxx'

就可以看到红色的文字显示在淡绿色的背景上:

其中-e的参数表示开启转义命令,31和46分别表示前景颜色和背景颜色。

注意,这一显示是由终端软件负责的,在一些边界条件上可能存在显示不一致的问题。例如,执行以上命令后,有些终端恢复成黑色字,有些终端则一直保持红色的字。

为避免这样的情况,可以加入重设命令:

echo -e '\e[31;46mxxxxxx\e[0m'

后面的 \e[0m 表示重置颜色。

维基百科对于这些颜色代码有具体的描述,还有关于如何控制颜色深浅、光标位置等等操作。

向其他程序发送命令

在类unix系统中(如Linux/MacOS等),程序的输入输出默认都是一个TTY设备。

有两个常用的命令:who可以显示当前用户打开的全部TTY设备,而tty则可以显示当前窗口所用的TTY设备。

因此,结合这两个命令,可以做到一些往常无法实现的功能,比如下图中,在一个tmux session中向另一个tmux session发送消息:

图片中左右两边是两个tmux session,中间有竖线分隔。黑色部分是一些被打码的私人信息。注意左边的echo命令,默认输出在左边。但是通过输出重定向,可以向右边的tmux session发送消息。TTY与nohup命令

了解TTY之后,我们还能对一些耳熟能详的操作有更深入的理解,比如让程序能够在终端失去连接后依然运行的nohup命令。

首先,我们需要了解,当退出终端(手动退出或者因为网络波动断网而退出)时,发送了什么:

系统给运行中的程序发送了hangup信号,如果程序不处理将被终止。系统关闭了这个终端对应的TTY设备。而这个TTY设备是程序默认的输入、输出来源。此时,当程序尝试输入、输出时,就会遇到错误。

因此,nohup的工作原理也非常简单,通过man nohup就可以看到:nohup - run a command immune to hangups, with output to a non-tty。简单来说,nohup让程序能够不受hangup信号的影响,并且将输入输出转移到一个非TTY的文件上,从而避免程序被关闭。

TTY与tmux

在tmux中开启的命令,也不会受到终端退出的影响。为什么呢?

这是因为tmux中开启的每个session都有自己的TTY设备。

我们首先登录一台服务器,通过who看到现在打开的TTY设备是/dev/pts/0。

而输入tmux命令进入tmux之后,可以看到新增了一个TTY设备,而且当前终端使用的TTY设备变成了/dev/pts/1。

由于只有第一个TTY设备是在登录时创建的,所以,终端退出时只会删除/dev/pts/0,对tmux内的程序没有影响。

ubuntu@VM-16-9-ubuntu:~$ who ubuntu pts/0 2023-03-13 13:55 ubuntu@VM-16-9-ubuntu:~$ tty /dev/pts/0 ubuntu@VM-16-9-ubuntu:~$ tmux ubuntu@VM-16-9-ubuntu:~$ who ubuntu pts/0 2023-03-13 13:55 ubuntu pts/1 2023-03-13 13:58 ubuntu@VM-16-9-ubuntu:~$ tty /dev/pts/1TTY与docker/k8s

当我们使用docker exec 或者 kubectl exec连接到某个容器时,经常会加上-it参数。其中的-t的含义,就是分配一个TTY设备。详见相关文档:

-t,--tty[=false] Allocate a pseudo-TTY

于是,执行完这些命令后,就与一个TTY设备启动了连接,可以当做一个正常的terminal来使用。(大家也可以试试去掉t参数,这时就像一个普通程序一样,你输入一个命令,它输出相应内容,没有tab补全,也没有各种显示与颜色)

总结

在我们日常使用中习以为常的一些功能,都是相关的计算机软件优化了几十年的结果。了解这些知识,我们能对身边的世界有更深刻的理解,也有助于我们学习新的知识、使用新的工具。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有