问题标签 [pty]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
3010 浏览

windows - Windows 上的 unbuffer 程序相当于什么?

嗨,根据这篇文章unbuffer通过伪终端(pty)连接到命令,这使得系统将其视为交互式进程,因此不使用任何标准输出缓冲。

我想在 Windows 上使用这个功能。我可以知道什么是unbufferWindows 上的程序等价物吗?谢谢。

0 投票
1 回答
2760 浏览

java - 在 java 中与 ssh 一起使用的伪终端

我正在编写一个程序来使用 ssh 连接到远程服务器并为用户提供 shell 终端。

我已经尝试过 JSch 和 sshj —— 两者都可以正确连接,但只需将它们的 shell 通道的输入/输出流连接到 System.in 和 System.out 就会产生时髦的输出。我知道为什么——JSch 和 sshj 的文档都说它们没有内置终端仿真,所以输入/输出很难看。(sshj 将此实现称为“基本 PTY”)

我还有一些终端仿真器可供选择:JTerm、DragonConsole 和 Terminator。

我的目标是启动终端仿真器窗口并执行类似于将输入/输出流从 shell 通道插入仿真器的操作。

诸如建议我自己处理与 shell 通道的输入/输出以摆脱垃圾字符的方法之类的替代方案也将受到赞赏——这是主要问题。

编辑:这是 sshj “基本 PTY”

这是JSch版本

0 投票
2 回答
348 浏览

linux - 确定一个 pty 是否有程序要求它输入

我正在使用 C 中的 openpty 创建一个 pty,并在主/父和从/子之间共享它。孩子可以 fork/exec 并将文件描述符传递给其他程序。我想向孩子注入命令,但如果我立即传递它们,它们就会迷路。我如何从父进程中得知有人阻止了来自标准输入的输入?我碰巧在 SUSE 10 上工作,但我更喜欢发行版独立的解决方案。

编辑:这个问题的答案对我来说仍然很有趣,但可能与问题无关。我稍后再谈。

代码的简化版本是使用脚本源代码(可能需要修复一些标题),并添加行

在大之前

主要。

我一直在从脚本执行 csh,但后来我注意到脚本命令正在转储一些垃圾(如在 vi 中所见)

到父母的标准输入。如果我改为执行 bash shell,则不会丢弃任何内容,并且程序会很好地注入命令。

我仍然对所问问题的答案感到好奇,但显然它不再与我的问题相关,因为还有其他事情发生。如果有人确实知道如何查看是否正在阅读 pty,请随时回答。

0 投票
1 回答
1227 浏览

c - 伪终端 (pty) 报告资源暂时不可用

我有一个 Pseudo-terminal slave,它给了我Resource Temporarily Unavailable (11)的读/写错误。我一直无法解决这个问题,但直到一周前我才知道任何 pty 的。所以,我可能会遗漏一些明显的东西。

根据我的阅读,这可能是由调用read()非阻塞 pty 引起的。但是,当我检查从属 ptyF_GETFL之后open(),该值显示它是一个阻塞文件描述符。

的输出F_GETFL显示该O_NONBLOCK标志已禁用,并且该O_RDWR标志已启用:

我什至尝试通过使用来确定它何时准备好将slavefd其视为非阻塞文件。select()但是,它只是每次都超时。

那么,如果设置为阻塞,为什么read()将errno设置为Resource Temporarily Unavailable ?slavefd看起来的标志F_GETFL正确吗?我还能尝试什么来缩小这个问题的原因?

更新:(更多信息)

我还不确定,但我认为 pty 从设备节点被 pppd 以某种方式锁定。有人告诉我,您可以回显到 pty slave,这似乎是真的,除非 pppd 正在使用它。

更新 2:(添加代码)

此更新显示了我如何打开从设备。由于我正在使用此应用程序进行调试,因此我只是直接使用argv[1].

问题解决了:

我试图读/写的从节点正在被 pppd 修改。当 pppd 控制 tty/pty 设备时,它将线路规程从更改N_TTYN_PPP。这意味着当你open()read()write()到从节点时,PPP 中间驱动程序正在被使用而不是 TTY 驱动程序。因此,aread()write()归结为完全不同的功能。查看N_PPP驱动程序,我发现了以下内容。这回答了我为什么要退回 EAGAIN 的问题。

0 投票
3 回答
1377 浏览

c++ - 套接字的 pty 功能

我正在编写 linux 守护程序,我想实现通过 telnet 配置其参数的能力。我有一个 cli 接口代码,使用带有历史和完成程序的 gnu readline 库编写,我想将该接口代码用于守护进程。

我尝试将标准输入/标准输出重定向到套接字,将 rl_instream/rl_outstream 重定向到套接字,读/写到主/从 pty,但没有成功。

类似的问题在这里问没有任何答案。

还阅读了这个问题,但我没有子进程。

我的问题是:

  1. 如何在单个进程中使用 pty 功能?
  2. 如果我只有单个进程,是否需要使用 master 和 slave pty?

代码示例(在 pty 设备上没有操作),预期结果 - readline 正常工作

非常感谢。

0 投票
2 回答
940 浏览

python - 为什么我不能在这个分叉的进程中读取标准输入?

下面的代码什么也不打印,但它应该重复打印出“a”。os.read(0, 1) 上的分叉进程阻塞。父进程确实在写入 stdin_master,但 stdin_slave 什么也没收到。有任何想法吗?

0 投票
1 回答
3227 浏览

python - 多路复用器

我正在尝试对 linux 上的串行端口进行多路访问。我正在使用一个只有一个串行端口的嵌入式系统,如果有多个进程与之通信会很好。

常见的用例是:

  • 一个主程序运行测试(发送命令和接收输出);
  • 另一个记录所有串口活动;
  • 在测试期间出现一些错误后,用户终端打开以发送其他命令和/或执行事后分析。

首先,我制作了一个简单的 python 脚本来打开 n 个伪终端对(加上串口),并使用 poll 语句将输入/输出定向到正确的位置:

如果每个 pty 都已连接,则此方法非常有效。如果有一些未连接的 pty,最终它的缓冲区会填满并在写入时阻塞。似乎我需要知道连接了哪些从站或某种按需 pty 开放。

我在这个问题上找到了一个巧妙的技巧,这个人只需要从串口部分读取数据,所以我修改了我的脚本:

哪个有效,但使用了 100% 的 CPU,因为读取器轮询充满了 POLLHUP 事件。

我想如果我使用 TCP 套接字而不是伪终端,我可以得到我想要的。缺点是我必须修改所有其他已经与终端一起使用的脚本才能使用套接字(我知道我可以使用 socat,我只是想要更简单的东西)。此外,还有所有的网络开销......

那么,有什么想法吗?

我不介意使用其他工具,只要设置简单。我也不介意使用其他语言,我最喜欢 Python。

0 投票
1 回答
947 浏览

macos - 从 Cocoa 应用程序控制交互式命令行实用程序 - ptys 问题

我正在尝试做的事情

我的 Cocoa 应用程序需要运行一堆命令行程序。其中大部分是非交互式的,所以我用一些命令行参数启动它们,它们做他们的事情,输出一些东西并退出。其中一个程序是交互式的,因此它会向标准输出输出一些文本和提示,然后期待标准输入上的输入,并且这种情况一直持续到您向其发送退出命令。

什么有效

仅将大量数据转储到标准输出然后终止的非交互式程序相对来说是微不足道的:

  • NSPipe为 stdout/stdin/stderr创建s
  • NSTask使用这些管道启动

那么,要么

  • NSFileHandle管道的另一端读取所有数据,直到流结束,并在任务结束时一次性处理它

或者

  • 从输出管道的另一端获取-fileDescriptors 。NSFileHandle
  • 将文件描述符设置为使用非阻塞模式
  • 使用每个文件描述符创建一个 GCD 调度源dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, ...
  • 恢复调度源并使用它处理它向您抛出的数据read()
  • 继续进行,直到任务结束并且管道文件描述符报告 EOF(read()报告读取 0 字节)

什么不起作用

对于交互式工具,这两种方法都完全失效。显然我不能等到程序退出,因为它位于命令提示符下,除非我告诉它,否则永远不会退出。另一方面,NSPipe缓冲数据,因此您以缓冲区大小的块接收它,除非 CLI 程序碰巧显式地刷新管道,而在我的情况下则没有。初始命令提示符比缓冲区大小小得多,所以我什么也没有收到,它就在那里。所以NSPipe也是不行的。

经过一番研究,我确定我需要使用伪终端(pty) 来代替 NSPipe。不幸的是,除了让它正常工作之外,我什么都没有。

我试过的

我创建了一个像这样的 pty,而不是 stdout 管道:

这给了我两个文件描述符;我把它slaveFD交给一个NSFileHandle,它被传递给NSTaskstdout 或 stdout 和 stdin 。然后我尝试从主端进行通常的异步读取。

如果我在终端窗口中运行我正在控制的程序,它首先输出 2 行文本,一行 18 字节长,包括换行符,一个 22 字节长,命令提示符没有换行符。在这 40 个字节之后,它等待输入。

如果我只是将 pty 用于标准输出,我会从受控程序收到 18 个字节的输出(正好是一行,以换行符结尾),仅此而已。在最初的 18 个字节之后,一切都在那里,没有更多的事件 - GCD 事件源的处理程序不会被调用。

如果我还将 pty 用于标准输入,我通常会收到 19 个字节的输出(上述行加上下一行的一个字符),然后受控程序立即终止。如果我在尝试读取数据之前稍等片刻(或调度噪音会导致短暂的停顿),我实际上会在程序再次立即终止之前获得整个 40 个字节。

额外的死胡同

NSFileHandle有一次我想知道我的异步读取代码是否有缺陷,所以我使用s 及其-readInBackgroundAndNotify方法重新做了所有事情。这与使用 GCD 时的行为相同。(我最初选择 GCD 而不是NSFileHandleAPI,因为在 中似乎没有任何异步写入支持NSFileHandle

问题

经过一天多的徒劳尝试,我已经到了这一点,我可以得到某种帮助。我正在尝试做的事情是否存在一些基本问题?为什么将标准输入连接到 pty 会终止程序?我没有关闭 pty 的主端,所以它不应该收到 EOF。撇开标准输入不谈,为什么我只能得到一行的输出?我在 pty 的文件描述符上执行 I/O 的方式有问题吗?我是否正确使用了主从端-控制过程中的主端,NSTask中的从端?

我没试过的

到目前为止,我只在管道和 pty 上执行了非阻塞(异步)I/O。我唯一能想到的是 pty 根本不支持这一点。(如果是这样,为什么会fcntl(fd, F_SETFL, O_NONBLOCK);成功?)我可以尝试在后台线程上阻塞 I/O 并将消息发送到主线程。我希望避免不得不处理多线程,但考虑到所有这些 API 看起来有多糟糕,它不会比尝试另一种异步 I/O 排列更耗时。不过,我很想知道我到底做错了什么。

0 投票
1 回答
940 浏览

gnu-screen - 如何绕过与 zssh 文件传输 (rz/sz) 的屏幕/byobu 冲突

我一直在尝试zssh,因为它似乎是一种快速/简单szrz方式来来回发送文件(本地 <-> 远程) over ssh。问题是我在远程服务器上使用byobu(基本上screen),这与文件的发送和接收有某种冲突。

http://zssh.sourceforge.net/FAQ

第 6 条指出:

这真是太糟糕了,因为运行byobu是我的远程管理工具包的重要组成部分,而且我还没有找到任何看起来像zssh.

任何人都可以想出一种zssh无需禁用即可开始工作的方法byobu/screen吗?我会自己解决问题,但是这种事情让我头疼(因为,我不知道为什么screen会与这样的文件传输过程发生冲突,所以解释会非常有帮助)。

此外,该问题的任何替代解决方案将不胜感激。

编辑: 想知道是否有办法快速退出byobu,执行zssh任务然后跳回上一个byobu会话......

0 投票
1 回答
1489 浏览

c++ - Linux 中伪终端的读写问题

我正在编写一个与外部进程交互的 C++ 程序。外部进程用 C# 编写并在单声道上运行。请注意,我无法修改 C# 代码,因为它不是我编写的程序。

在这方面,我首先使用管道,当然我后来意识到它是完全缓冲的,因此我遇到了很多同步问题。本质上,外部进程必须在每次写入后刷新其输出,这是不可能的。

我接下来要尝试的是文件,但是我发现在我的情况下使用伪终端更合适。这是我编写的一些示例代码:

假设正在处理 select 的 fdset 和 fdclr。

在父进程中观察到以下问题:

  1. 有时 read 返回时 readBytes > 0 但缓冲区中没有任何内容
  2. 有时,写入终端的任何内容都会被回读
  3. 一些垃圾值,例如 ^]]49]1R 被转储到终端上(这是实际的终端,即我的输出窗口)

PS:外部进程用C/C++编写时,不会出现这个问题。仅当我以单声道运行 C# 程序时。