stdin/stdout/stderr 那点事儿
本文起源于:swap 的扩容(及其他)
经常写简单命令行程序的人可能会知道,这些是标准输入输出文件和标准出错文件,在平时一般会被重定向到屏幕上,你可以看到它实际上指向的是/proc/self/fd/*
[root@quality-unicorn-3 ~]# ls /dev -alh | grep std
lrwxrwxrwx 1 root root 15 Feb 7 08:29 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Feb 7 08:29 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Feb 7 08:29 stdout -> /proc/self/fd/1
而/proc/self/fd/*
又是啥呢?
用同样的套路可以看到:
... /proc/self/fd/0 -> /dev/pts/0
... /proc/self/fd/1 -> /dev/pts/0
... /proc/self/fd/2 -> /dev/pts/0
实际上在这里的self
指的就是程序自身,也就是当前所使用的bash
程序,而下面fd中的0,1,2等就是对应打开文件的符号链接,它们都指向了同一个设备:/dev/pts/0
。而利用secureCRT连接的设备代号即为pts/0
。
到这里为止一切都明白了,当我们使用终端连接的时候,在操作系统中创建了一个设备pts/0
,而我们所做的所有交互都是通过这个设备进行。stdin
/stdout
/stderr
都被重定向至这个设备中,也就意味我们可以通过这个设备来给连接时创建的bash
发送与接受命令。使用ps -A | grep bash
可以看到我们启动的bash
所对应的设备描述文件,即我们自己的窗口
[root@quality-unicorn-3 ~]# ps -A |grep bash
3503 pts/0 00:00:00 bash
如果有很多个人(或者你自己开很多个窗口)同时连接,就可以看到类似如下的内容:
[root@quality-unicorn-3 ~]# ps -A |grep bash
3503 pts/0 00:00:00 bash
3536 pts/1 00:00:00 bash
既然我们已经知道pts/*
究竟代表什么,就可以玩一些骚操作了,比如:
[root@quality-unicorn-3 ~]# echo cnm > /dev/pts/1
这样就可以往另一个人的界面中发送文字片段,或者:
[root@quality-unicorn-3 ~]# cat /dev/pts/1
这样别人输入的命令就有概率出现在你的屏幕上(有概率是因为他的输入要么出现在他自己的屏幕上,要么出现在你的屏幕上,两边不会同时出现,测试发现基本是等概率的),导致你能猜到他要输入什么信息,并且他经常需要按好几次按键才会成功。还可以把以上两点结合起来,作用读者可以自己尝试:
[root@quality-unicorn-3 ~]# cat /dev/pts/1 > /dev/pts/1
顺便说一句,如果不是使用ssh远程连接,在这里的pts/*
实际上应该为tty/*
,具体背景可以在参考资料里找。
学会了学会了 明天leader ssh服务器的时候试试