【发布时间】:2018-02-14 06:43:21
【问题描述】:
我正在尝试在 Python 中复制此 socat 命令的行为:
socat PTY,link=/tmp/mypty tcp-listen:1234
到服务器端口 1234 的 TCP 连接将连接到 /tmp/mypty(到 /dev/pts/N 的链接),并且运行 screen /tmp/mypty 将允许用户与另一端的任何东西进行交互那个连接。换句话说,如果它用于连接到那个监听端口:
socat exec:'bash -li',pty,stderr,setsid,sigint,sane tcp-connect:172.16.30.3:1234
然后运行screen /tmp/mypty 会将用户连接到在TCP 连接另一端运行的bash 实例。
获取 TCP 套接字很简单。我可以使用 os.openpty() 获得 PTY,这会产生一对文件描述符,它们只是整数。
我无法做的是以一种可以无缝地来回传递数据的方式挂钩该套接字和那些文件描述符。如果它们都是套接字,那将是微不足道的;使用带有 select() 的循环将新的 read 数据传递给另一个套接字的 write。
我尝试过的:
- 使用 socket.fromfd 使用 PTY 文件描述符之一构建套接字。这导致
OSError: [Errno 88] Socket operation on non-socket。此代码示例,其中 clisock 是一个有效的套接字:
导致此错误:
PTY:打开 /dev/pts/2 CLISOCK: PTYMSOCK: PTYSSOCK: 线程 Thread-1 中的异常: 回溯(最近一次通话最后): _bootstrap_inner 中的文件“/usr/lib/python3.6/threading.py”,第 916 行 自我运行() 文件“/usr/lib/python3.6/threading.py”,第 864 行,运行中 self._target(*self._args, **self._kwargs) sockToPty 中的文件“./tcpmux.py”,第 62 行 对等[袜子].send(数据) OSError: [Errno 88] 非套接字上的套接字操作如果我使用 AF_INET 而不是 AF_UNIX 则没有区别。
- 使用 os.dup2() 将 SSLsocket 的 fileno() 映射到标准输入、标准输出和标准错误,然后运行 os.openpty()(如 tcp_pty_bind.py)。这不会产生任何错误,但是当我使用
screen打开 PTY 时没有明显的数据流。
几乎所有 Python PTY 示例都集中在 pty.spawn() 上,因此很难找到任何使用 PTY(诚然晦涩)的示例代码。
旁注:我使用 os.openpty 而不是 pty.openpty 只是因为似乎没有意义。 pty 模块似乎被宣传为更多的可移植性,但没有更多的可移植性,而且我在 Linux 上工作,所以可移植性不是问题。因为我得到了正确的 os.ttyname() 的有效文件描述符,所以我没有理由质疑 openpty() 不能正常工作。
【问题讨论】:
标签: python python-3.x sockets pty