本文介绍一种通过文件描述符重定向终端输入/输出的方法。
一些嵌入式设备,一般都会留有调试串口,经由RS232/485标准与PC的COM口相连,将打印输出在PC上显示,并可以接收PC端的输入,如下图所示:
设备出厂部署后,不方便接调试串口,查看设备输出就变得比较困难,不利于问题定位。 如果设备具有联网能力,我们可以通过telnet或者ssh登录到设备上,进行远程调试。 这时候就面临一个问题:如何把设备的打印信息显示出来?
常见做法有以下几种:
以上几种做法各有优劣,下面介绍一种通过文件描述符重定向终端输入/输出的方法。
下图展示了Linux系统中标准输入/输出(STDIN/STDOUT)与控制终端的关系,其中ttyS0即串口:
用户通过telnet或者ssh登录后,会动态生成一个控制终端(比如/dev/pts/0),如下图所示:
我们是否可以把标准输入/输出(STDIN/STDOUT)从ttyS0解绑,重新映射到pts0上呢?答案是肯定的。
如下图所示,重新绑定后,打印就可以直接输出到telnet或者ssh对应的控制台,经由网络传输到PC上;同时,也可以从PC上接收输入(如果应用程序监听了STDIN,PC上的输入就可以直接被应用程序读取到,不重定向的话是收不到的)。
注:在某个控制终端执行的命令(启动的程序),默认绑定当前终端,所以正常情况下telnet或者ssh到设备后,执行ls
等命令,输出都是在当前终端。
具体实现代码可以参考https://github.com/sigusr1/redirect_console。
如下图所示,应用程序中需要集成一个Server,用来接收Client发送来的重定向指令。
相关过程说明如下:
dup2(fd_out_bak, STDOUT_FILENO)
就可以还原原来的终端,达到以下效果:一个telnet已经把打印拉过来了,当它不想用的时候,发送还原指令,打印就又跑到原来的终端那边了。 fd_out_bak = dup(STDOUT_FILENO); fd_in_bak = dup(STDIN_FILENO);
优点:
缺点:
cat /proc/kmsg
命令可以远程实时查看内核打印)