telnet登陆目标板无法接收printf打印信息
CPU : ARM9BOARD : AT91RM9200
问题描述:
之前使用的是vxworks操作系统,串口和telnet连接目标板都可以接收到打印信息。因项目需求操作系统由vxworks替换为linux,
应用程序起来后,telnet到目标板接收不到printf的打印信息,但是串口可以正常接收。
个人猜测可能是默认输出到串口,因此telnet无法接管这些打印信息。
各位大侠有没有遇到这种情况,如何才可以再打印串口时,打印信息输出到串口,如果telnet连接到目标板,则输出telnet终端呢。
初学linux,多多赐教,多谢! 这是不可能达到的:
1. 内核的printk把信息打到哪里去呢?这是在内核的命令行参数console=ttyXXX里指定死了,比如console=ttySAC0表示printk的信息输出到串口0
2. telnet上去之后,printf的输出信息是输出到一个“虚拟的终端”去的,你可以用ps命令看一下这个telnet对应的/bin/sh进程ID,ls/proc/进程ID/fd -l 就可以知道这个虚拟的终端对应什么文件。
你可以看到0、1、2这3个文件都是对应一个“临时生成的虚拟的文件”
3. 所以,内核的信息不可能在telnet界面显示出来,你想看的话,可以为dmesg命令查看 回复 2# work4home
谢谢答复。
发现一点细节:
如果在文件系统起来后,telnet到目标板(此时是启动一个sh的,有一个PID,如果虚拟终端是/dev/pts/0),然后手动启动应用程序,应用程序的打印信息是可以接收到的。
但是关闭掉这次连接的终端后,再次telnet到目标板,就无法收到应用程序的打印信息,因为此时是又启动了一个sh,PID也跟上次的不一样了,最主要的是虚拟终端为/dev/pts/1。
意思就是不管你关闭多少次,再telnet到目标板,原来可以接收消息的虚拟终端/dev/pts/0一直分配不到,但是其他的终端,如/dev/pts/1就可以再次使用。
现在疑惑的是,这个打印信息是与首次分配的PID有关,还是与虚拟终端设备号有关。
也在考虑是不是与busybox里的telnet代码相关。也在考虑是不是需要在那里加重定向输出的代码或者脚本。
如果不能实现telnet接管打印信息的话,那么对于linux产品问题定位很不方便,100个产品的随机问题不可能找100个PC,使用100个串口都接上吧。
我也尝试了dmesg,但是只打印了内核启动的信息,应用程序的打印信息不存在。
谢谢work4home,还请多多交流。
每次telnet上去,就会生成一个/dev/pts/x文件,每次都不会相同的;
你telnet上去后,会有一个/bin/sh,在这个/bin/sh里启动应用程序,那么这个/bin/sh就是这个应用程序的父进程;当你把这个telne连接关闭后,/bin/sh会退出,它的子进程也会退出。
所以你说的“再次telnet到目标板,就无法收到应用程序的打印信息”,原因是这个应用程序早就死掉了。
应用程序的打印信息,与它的父进程的0、1、2三个文件相关。在telnet界面,这3个文件对应虚拟的设备。
根据这个原理,你可以在应用程序里close(0),close(1),close(2),然后再打开3个文件,这样printf就可以输出到这些文件去了。
通常的做法是:不直接用printf,而是自己实现打印,打到文件去、或是发到服务器去。 回复 4# work4home
首先谢谢work4home兄弟的交流。
根据work4home兄弟的说话,本人有个想法,应该是可以实现telnet接管打印信息,还请work4home给点意见。
这个打印信息的函数不能使用printf,应该自己实现一个打印函数,把输出信息重定向到新生成的虚拟终端pts上。当遍历终端时没有发现有虚拟终端,或者此终端退出时,需要重定向到console。
原本有想法,自己参考busybox代码实现telnet服务器,这个工作量还是比较大的,暂时放弃。另外监听socket连接,输出重定向到sock句柄,也不可行,无法区分其他类型的tcp连接。
因此起一个线程来做重定向的事,应该是易行的一个方法。只是目前还不知道有没有什么系统函数可以使用,目前想到一种笨的查找方法。先查找进程PID,再由进程PID去/proc/PID/fd 查找终端,再做重定向工作。 work4home 发表于 2012-01-31 17:38 static/image/common/back.gif
每次telnet上去,就会生成一个/dev/pts/x文件,每次都不会相同的;
你telnet上去后,会有一个/bin/sh,在这 ...
纠正work4home兄弟一句话。“每次telnet上去,就会生成一个/dev/pts/x文件,每次都不会相同的”
这个是可以相同的,不同的进程ID。请看下面:
# ps
353 root 1696 R -sh-------这个是telnet的进程ID
372 root 1684 R ps
# ls /proc/353/fd -l
lrwx------ 1 root root 64 Jan1 00:28 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan1 00:29 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan1 00:29 10 -> /dev/tty
lrwx------ 1 root root 64 Jan1 00:29 2 -> /dev/pts/0
#
然后我关闭后,再次telnet到目标板:
# ps
374 root 1692 S -sh
375 root 1684 R ps
# ls /proc/374/fd -l
lrwx------ 1 root root 64 Jan1 17:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan1 17:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan1 17:51 10 -> /dev/tty
lrwx------ 1 root root 64 Jan1 17:51 2 -> /dev/pts/0
# 这个问题已经解决了
需要写点代码就可以实现。
下次再贴方法,下班回家了 需要在接管打印的进程内,做一个线程,目的是接收需要打印的虚拟设备。
比如现在是在/dev/console 打印信息的,此时我们telnet到目标板,tty看到设备名/dev/pst/0,我们需要把原来的打印信息console被pst/0接管。
主进程做一个服务端的代码,监听某个端口,当客户端有接入时,接收客户端消息,主要使用dup2来实现输出的重映射功能。
客户端代码主要是连接服务器,发送虚拟终端设备名。
思路就是这样了 回复 8# 150159413
能附上代码吗,我也正做相似功能
万分感激~~ 没想到还有人跟我碰到一样的问题哈,mark一下,慢慢看。
我就自己重写一个函数定向到文件,然后cat一下好了。
不过我发现普通函数printf telnet是能显示的,但是线程里的printf竟然不显示,我晕死。
页:
[1]
2