我有一台通过USB将信息发送到我的计算机的设备。Arch Linux的创建一个名为文件设置该设备ttyUSB0
在/dev/
。我一直在使用GTKterm
接收此传入的信息并将其显示在模拟的终端窗口中。
我的问题是,如何精确地GTKterm
读/写该ttyUSB0
文件,我应该从哪里开始学习如何实现类似的功能?也就是说,以最基本的形式,我如何将字符写入ttyUSB0
,或者相反,如何接收字节并将其写入文件?
screen
和/或miniterm
编程。
我有一台通过USB将信息发送到我的计算机的设备。Arch Linux的创建一个名为文件设置该设备ttyUSB0
在/dev/
。我一直在使用GTKterm
接收此传入的信息并将其显示在模拟的终端窗口中。
我的问题是,如何精确地GTKterm
读/写该ttyUSB0
文件,我应该从哪里开始学习如何实现类似的功能?也就是说,以最基本的形式,我如何将字符写入ttyUSB0
,或者相反,如何接收字节并将其写入文件?
screen
和/或miniterm
编程。
Answers:
TTY是可以像其他任何文件一样使用的文件。您可以使用您语言的标准文件打开工具来打开它们,并从中读取或写入。它们具有一些与“普通”文件不同的特殊行为,但是基本知识是相同的。最后,我将介绍一些特殊情况,但首先是一个实验。
您可以从常规终端直接进行一件有趣的事情。运行tty
,它将打印如下行:
/dev/pts/2
那是您的终端在其中运行的TTY设备。您可以向该终端写一些东西:
$ echo Hello > /dev/pts/2
Hello
$
您甚至可以从中读取:
$ read X < /dev/pts/2
hello
$ echo $X
hello
$
(read X
是sh的“将标准输入中的一行读入变量X”命令; <是将/ dev / pts / 2用作read命令的标准输入;我键入了第一个“ hello”,第二个已打印出来) 。
如果打开另一个外壳,例如使用screen
或xterm
,则可以echo spooky > /dev/pts/2
在该外壳中运行run ,以使文本显示在原始终端上,其他命令也是如此。所有这些只是您的shell在不知道它是TTY的情况下打开文件。
这是一个非常简单的C程序,它按照您的要求执行操作,并将单个字符写入/ dev / pts / 3,然后从中读取单个字节:
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main() {
char byte;
int fd = open("/dev/pts/3", O_RDWR);
write(fd, "X", 1);
ssize_t size = read(fd, &byte, 1);
printf("Read byte %c\n", byte);
return 0;
}
连接到外壳或终端仿真器的真实TTY设备在那里会有有趣的行为,但是您应该得到一些回报。
要访问终端,您需要具有使用权限。这些只是您看到ls -l
并设置的标准文件权限chmod
:您需要具有读取权限才能打开文件并进行读取,并具有写入权限才能写入文件。支持您终端的TTY将归您所有,但其他用户的TTY将不属于您,而USB设备的TTY可能取决于您的配置。您可以像以往一样更改权限。
就编写可以使用它的程序而言,您不需要做太多特别的事情。您可以在示例中看到,您不需要做的一件事就是每次都关闭文件以使另一端读取数据:TTY文件的作用就像管道一样,只是在数据进入时就双向推送。当我向TTY写文本时,它立即出现,之后再阅读时,已经没有什么在等我了。它不是像写在那里得到的数据保存在磁盘上一个普通的文件-它被立即传递给对方,或者存储在内存中,直到有人读它。
您可能希望使用选择功能,以便在等待设备说出某些内容时可以执行其他操作,但是如果您乐于等待数据通过,则可以使用阻塞读取并让操作系统执行解除。
要记住的一件事是内核中的缓冲区大小可能有限,并且如果您一次写入大量数据,则可能最终毫无意义地阻塞。如果这可能是个问题,请与一起使用非阻塞IOopen("/dev/...", O_RDWR | O_NONBLOCK)
。两种方法的原理都是相同的。
sudo echo Hello > /dev/tty4
当我在桌面环境中时,我正在尝试,但是bash: /dev/tty4: Permission denied
如果未登录tty4,我会得到。但是,如果我登录到tty4,一切正常。这是什么原因呢?
ls -l /dev/tty4
> /dev/tty4
部分不是由当前用户echo
启动的子流程的sudo
一部分,而是该sudo
流程本身的一部分。当前用户的文件权限而不是root用户。