如何判断哪一对伪tty端口相互连接

How to determine which pair of pseudo tty ports are connected to each other

我有两个 python 程序,它们通过点对点 tty 串行连接相互通信。为了模拟连接,我使用 socat 创建一个双向字节流,如下所示:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

控制台returns如下,表示现在连接在一起的两个pty端口:

2018/04/15 22:33:03 socat[18197] N PTY is /dev/pts/2
2018/04/15 22:33:03 socat[18197] N PTY is /dev/pts/3
2018/04/15 22:33:03 socat[18197] N starting data transfer loop with FDs [5,5] and [7,7]

那我得手动修改两个程序,分别指定串口连接,如:

在程序中A.py:

import serial
...
ser = serial.Serial('/dev/pts/2')

在程序中B.py:

import serial
...
ser = serial.Serial('/dev/pts/3')

我想要的是一个脚本,它可以设置 socat 连接,然后执行 A.py 并将一个端口号作为参数传递给它,并使用另一个端口执行 B.py作为参数传递给它的数字。

我试过 bash 脚本,但 socat 命令阻塞,我无法捕获它的 stderr 输出以将其放入变量中。如果可以的话,我就可以解析变量并开始我的快乐之旅。

有什么想法吗?或者也许有更好的方法来做到这一点?

谢谢!

您可以 运行 socat 使用低级别 Popen class 在 python 中不阻塞。您需要重定向 stderr 以便您可以扫描它以查找 pty 名称,但是您可以在获得所需信息后将其交给后台线程。

import sys
import subprocess as subp
import threading
import shutil
import re

socat_proc = subp.Popen(['socat', '-d', '-d', 'pty,raw,echo=0', 'pty,raw,echo=0'],
    stderr=subp.PIPE)

try:
    # scan output for 2 ptys
    ptylist = []
    for line in socat_proc.stderr:
        line = line.decode().strip()
        print(line)
        pty = re.search(r"N PTY is (.+)", line)
        if pty:
            ptylist.append(pty.group(1))
            if len(ptylist) == 2:
                break

    if socat_proc.poll() is not None:
        print("badness. socat dead.")
        exit(2)

    # background thread consumes proc pipe and sends to stdout
    socat_thread = threading.Thread(target=shutil.copyfileobj, 
        args=(socat_proc.stdout, sys.stdout))
    socat_thread.daemon = True
    socat_thread.start()

    print("pty", ptylist)

    # now you can start your programs...

finally:
    socat_proc.terminate()