问题
I have two python programs that are to communicate with each other over a point to point tty serial connection. To simulate the connection, I create a bi-directional byte stream using socat as here:
socat -d -d pty,raw,echo=0 pty,raw,echo=0
The console returns the following, indicating the two pty ports that are now connected together:
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]
Then I have to modify each of the two programs manually to specify the serial connection for each, such as:
In program A.py:
import serial
...
ser = serial.Serial('/dev/pts/2')
In program B.py:
import serial
...
ser = serial.Serial('/dev/pts/3')
What I'd like is a script that would set up the socat connection, then execute A.py with one port number passed to it as an argument, and execute B.py with the other port number passed to it as an argument.
I've tried a bash script, but the socat
command blocks and I can't capture its stderr output to put it in a variable. If I could, I could then parse the variable and be on my merry way.
Any ideas? Or maybe a muy better way to do this?
Thank you!
回答1:
You can run socat
without blocking using the low level Popen
class in python. You need to redirect stderr
so that you can scan it for the pty name, but then you can hand it off to a background thread after you get the information you want.
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()
来源:https://stackoverflow.com/questions/49847650/how-to-determine-which-pair-of-pseudo-tty-ports-are-connected-to-each-other