我目前正在尝试记录来自 /dev/ttyUSB0 的所有通信,同时能够将 minicom/screen 连接到同一设备进行交互。
我尝试了几个工具和教程,但它们似乎都占用了设备,所以我无法使用终端程序连接到它。
然后我遇到了socat。这听起来很有希望,尽管它能够将 /dev/ttyUSB0 重定向到 PTS 并将传输的数据记录到文件中。
这个想法是:
硬件 - /dev/ttyUSB0 <---> socat/logging <---> /dev/ptyX <---> minicom
以前有人这样做过吗?
任何帮助表示赞赏。克里斯
当终端设备处于熟模式时,输入到终端的字节被内核缓存和处理,一些字节用于行编辑和“消费”,使一次read返回一行。
但是对于 pty,输出到 master fd 可以作为从 slave fd 的输入读取,反之亦然,所以我的问题是:
pty 设备是否有两个独立的输入缓冲区,不像 tty,每个 tty 设备一个缓冲区?
我正在尝试弄清楚如何在我拥有的 pt master 上可靠地循环读取。\n我打开 ptmx,照常授予并解锁它:
\n\n* ptmx stuff */\n/* get the master (ptmx) */\nint32_t masterfd = open("/dev/ptmx", O_RDWR | O_NOCTTY);\nif(masterfd < 0){\n perror("open");\n exit(EXIT_FAILURE);\n};\n\n/* grant access to the slave */\nif(grantpt(masterfd) < 0){\n perror("grantpt");\n exit(EXIT_FAILURE);\n};\n\n/* unlock the slave */\nif(unlockpt(masterfd) < 0){\n perror("unlockpt");\n exit(EXIT_FAILURE);\n};\n\ncomms_in->ptmx = masterfd;\nRun Code Online (Sandbox Code Playgroud)\n\n接下来我保存奴隶的名字(是的,我知道 sizeof(char) 始终为 1)
\n\n/* get the path to the slave */\nchar * slavepathPtr;\nchar * slavePath;\nsize_t slavepathLen;\nif((slavepathPtr = ptsname(masterfd)) == NULL){\n perror("ptsname");\n exit(EXIT_FAILURE);\n}else{\n slavepathLen = strlen(slavepathPtr);\n slavePath = (char *) malloc(sizeof(char) * (slavepathLen …Run Code Online (Sandbox Code Playgroud) 当我打开一个终端模拟器(xterm例如)时,xterm会有一个主端(/dev/ptmx)和一个从端(/dev/pts/#)。
但是当我打开一个虚拟终端(按Ctrl+Alt+F#)时,虚拟终端是否也连接到了一个主机?还是直接连接到/dev/tty#没有主站的从站()?
我试图了解ssh的-t选项:
-t强制伪终端分配。这可用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。多个 -t 选项强制 tty 分配,即使 ssh 没有本地 tty。
所以,TTY 是一个设备。引用 TTY 的一种方法是通过描述符(通过打开 TTY 设备获得)。STDIN、STDOUT 和 STDERR 是描述符。但它们不一定是指 TTY 设备。-t选项强制它们引用 TTY 设备。这是为了理解这个选项的作用的正确推理方式吗?
使用普通的 STDIN、STDOUT 和 STDERR 可能无法实现的 TTY 有什么特别之处?
-t欢迎使用选项用例的示例。
通过哪种机制ssh分配该 TTY?是ssh在服务器上还是在客户端上创建新的 TTY?如何检查这个?(/dev/必须出现一个新节点或其他什么……)这个新的 TTY 如何与现有的 STDIN、STDOUT 和 STDERR 相关联?
我读过这里是ssh被认为是一个PTY。为什么?如果我ssh在控制台中运行命令(比如在 Debian 服务器中),这里的“pty”方面从何而来ssh?对我来说,这就像我在使用任何其他实用程序,如cat或sed,那么这里的“pty”方面从何而来?
在screen或者tmux使用这个术语似乎更合理(尽管我认为它很不常见,这些应该被命名为“多路复用器”)。
我经常用来tee /proc/self/fd/2向 stdout 和 stderr 显示一些内容,捕获 stdout,同时仍将所有输出保留到 stderr。
例如,我有一个do.sh:
STD_OUT_STR=$(CMD ARGS ... 2>&1 | tee /proc/self/fd/2)
# handle STD_OUT_STR ...
...
Run Code Online (Sandbox Code Playgroud)
这效果非常好。
例如,
./do.sh
Run Code Online (Sandbox Code Playgroud)
基本上是这样运行的:
bash -c 'echo hi | tee /proc/self/fd/2'
Run Code Online (Sandbox Code Playgroud)
输出
hi
hi
Run Code Online (Sandbox Code Playgroud)
然而,有一天我在 下运行它sudo -u A_USER ./do.sh,它失败了。
sudo -u A_USER ./do.sh'
Run Code Online (Sandbox Code Playgroud)
其本质上是运行:
sudo -u A_USER bash -c 'echo hi | tee /proc/self/fd/2'
Run Code Online (Sandbox Code Playgroud)
输出
tee: /proc/self/fd/2: Permission denied
hi
Run Code Online (Sandbox Code Playgroud)
到目前为止,我必须遵循以下解决方法:
sudo -u A_USER bash -c 'echo hi | tee >(cat >&2)'
Run Code Online (Sandbox Code Playgroud)
我知道这是出于安全原因:不与其他用户共享当前用户的 …
有几个点可以通过 I/O,其中一些(据我所知)是 shell、pty、tty、termios、终端模拟器应用程序。在大多数终端模拟器中,长命令行(超过当前 $COLUMNS 的命令行)在用户通过按 Enter 提交命令之前换行到一个新行。此外,当如预期的那样从命令行中删除适当数量的字符时,该行将向后换行到上面的行。
我的问题是:这种魔法通常在哪里处理?它是 termios 设置,还是 shell 的一部分,还是终端模拟器应用程序对此负责?
有关更多上下文,我在 Ubuntu 上使用 Terminator 终端模拟器应用程序 - 换行工作非常好(所以我的 $PS1 提示应该没有问题)。但是我正在开发我自己的终端模拟器应用程序,它与 go pty spawner (github.com/kr/pty) 一起工作,我遇到了长行没有换行的问题,但是同一行。
如果我这样做ls | less,ls检测到它没有连接到终端,这很公平。不同之处在于less 被连接到终端。在此设置中,ls可以生成彩色和列化输出目标终端,并less可以正确处理它。您可以使用 使颜色正常工作ls --color=force | less -r,但这需要更多的输入,而且它不处理列。
如果有一个开关less可以告诉连接到它的任何东西将其视为真正的终端,那就太酷了。因此,您可以ls | less -T在less.
有没有做过这样的事情?
或者less像它这样的寻呼机真的可以自己做到这一点,还是需要 shell 的合作?例如,shell 是否需要设置一个伪终端ls来连接?