说起这几个东西,需要提一下几十年前的计算机。40几年前,计算机有点大,就像下图那样:
这么大的计算机需要控制台(console)来配置、管理和监控,所以就有了下面这个东东(console):
控制台需要连接显示设备,当时的技术要求连接显示设备的线缆要短,所以控制台一般和主机放在一起。
当多用户使用主机时候,不可能一起挤在一个房间里去抢输入输出设备吧。所以就有了远程连接的终端(terminal),就是下图这个东西:
tty原意是远程输入机(teletypewriter)的意思。现在在unix系统中,tty的意思是 text terminal 的意思。unix系统中的tty跟下图的东东没什么关系了。
上面给出的物理设备在Unix-like系统中依然存在,只不过被抽象成了设备文件了(device file),毕竟Unix中一切皆文件。在 /dev
目录下,可以找到他们的影子。
/dev/console 是一个 字符型的设备文件。
$ ls -l /dev/console
crw------- 1 root root 5, 1 Sep 1 20:25 /dev/console
在 GNU/Linux 和 Mac OS X 上,都有terminal程序,打开一个 terminal 程序就对应一个 tty (text terminal) 设备文件。做一个实验验证一下。
打开一个 terminal:
$ echo 'haha' > /dev/tty
haha
往 /dev/tty
写入内容会在当前terminal里回显。
如果同时存在两个terminal呢?再打开一个terminal试试看:
$ echo 'haha' > /dev/tty
haha
同样再当前terminal回显,但是回头看看一个terminal,并没有显示‘haha’。
其实每次打开terminal时会有个唯一的tty文件与其对应,上面第一次打开的terminal 对应的是 /dev/ttys000
, 第二次打开的terminal对应的是/dev/ttys001
。而
/dev/tty
会根据当前活动的terminal去找到对应文件ttys000或者ttys001。
基于上面的解释,可以实现在一个terminal上向另外一个terminal上写内容:
在第一个terminal上执行:
$ echo haha > /dev/ttys001
haha 会显示在第二个terminal上。
知道了tty,pty(pseudo tty)伪tty(text terminal)就没什么玄妙的了。pty在什么场景下用到呢?使用 ssh 客户端 远程连接到服务器系统上,那么用户操作的文本界面就是一个虚拟终端,对应一个/dev/ptys
。 dev/pty可以有多个,比如 /dev/ptys1
, /dev/ptys2
等,对应多个ssh连接。
利用上面的知识,可以在伪终端上向其他用户发送消息,同样其他用户可以发送消息过来,简直就是IM通讯工具啊。
实例:
1. 使用w
命令找到当前系统登录的用户以及其所在的伪终端。
$ w
lijianyo pts/28 172.23.0.48 14:56 0.00s 0.40s 0.04s sshd: lijianyong [priv]
damon pts/30 172.23.0.48 15:36 1:58m 0.06s 0.06s -bash
输出的第一列是用户名,第二列是其伪终端。
2. 给用户发消息
$ echo 'hello damon, how about go out for fun this evening?' > /dev/pts/30
其实有个Linux工具write
可以做同样的事儿,可以试试看。
在打开对第一个终端上(pts/28)执行:
write lijianyong pts/30
然后进入“等待你输入消息“对状态,继续输入,回车后输入对内容会显示在 pts/30终端上。
顺便提一下,write 命令受 mesg 命令影响。mesg 控制着其他用户是否有权向你的终端写入消息。当对方(比如pts/30)上执行了 mesg n
命令,表示关闭其他用户当写入权限。这时如果使用write lijianyong pts/30
就发送消息了。
但是可用通过 向 /dev/pts/30 写入消息绕过 mesg 的限制。