我有这个测试程序
import sys
for line in sys.stdin:
print(line.strip())
print("DONE")
如果我让它从真实设备(FTDI)打印出行
python3 demo.py < /dev/ttyUSB0
然后它打印我发送的每一行,然后当我拔出 USB 电缆时,我看到DONE
消息
另一方面,如果我用 socat 创建一个假 tty
socat -d -d pty,raw,echo=0,link=ttyFake pty,raw,echo=0,link=ttyFake.interface
然后使用python程序来监控假设备:
python3 demo.py < ttyFake
我可以像这样向它发送消息
echo test >> ttyFake.interface
他们被打印出来
但如果我用 SIGINT 或 SIGTERM 停止 socat 进程,我会得到如下信息:
$ python3 demo.py < ttyFake
test
Traceback (most recent call last):
File "~/serial-experiment/demo.py", line 3, in <module>
for line in sys.stdin:
OSError: [Errno 5] Input/output error
我也尝试过这个但没有运气:
$ echo -ne '\004' >> ttyFake.interface # send ^D
有没有办法让 socat 模拟拔出行为?我只需要一种更好的发送方式吗^D
?
子问题:我真的不知道^D
进程在标准输入中检测到的内容是否已确定输入已完成,或者只是您发送到终端模拟器以结束输入的内容。
答案1
我有一个解决方法可以让我的测试成功。这很容易成为问题的一部分 - 所以也许我正在尝试利用“坎宁安定律”(坎宁安本人似乎与此无关)
$ mkdir solution
$ cd solution
$ cat > demo.py
import sys
for line in sys.stdin:
print(line.strip())
print("DONE")
$ # make sure you ctrl+D at then end
$ mkfifo ttyConnector # DIFFERENT FROM QUESTION
$ socat -d -d pty,raw,echo=0,link=ttyFake pty,raw,echo=0,link=ttyFake.interface
新航站楼:
$ cd solution
$ cat > ttyConnector < ttyFake # DIFFERENT FROM QUESTION
新终端:(我们称其为应用程序终端)
$ cd solution
$ python3 demo.py < ttyConnector # DIFFERENT FROM QUESTION
新航站楼:
$ cd solution
$ cat > ttyFake.interface
test
test
test
$ # make sure you ctrl+D at then end
(确保最后 ctrlpython3 demo.py < ttyConnector+D )
现在看看应用程序终端
$ python3 demo.py < ttyConnector
test
test
test
即使我们结束了到 pty 的传输,fifo 仍然打开
但返回 socat 终端并按 ctrl+c,然后查看应用程序终端
$ python3 demo.py < ttyConnector
test
test
test
DONE
因此,我似乎可以通过 fifo 传递所有内容并杀死 socat 来模拟从 USB 拔出 FTDI 的行为。我有两个程序通过 pty 对连接在一起(模拟 FTDI 设备的程序和侦听的程序)。我可以使用此解决方法(目前),因为侦听程序仅打开 pty 对的末尾进行读取,而假设备则进行读取和写入,而测试本身则进行写入。
/--> P --> FIFO --> demo.py
FAKE DEVICE T
\<-- Y <-- TEST
如果我只需要在两端进行单向通信,我会跳过 socat,而只使用 fifo。
FAKE DEVICE --> FIFO --> demo.py
如果我需要完整的双向通信,我将需要真正的解决方案,但我还不知道。
/--> P -->\
FAKE DEVICE T demo.py
\<-- Y <--/
因为如果 demo.py 期望读取和写入相同的路径,那么插入两个 fifo 就不会那么容易了
所以我仍然希望找出我需要做什么才能在没有这种解决方法的情况下很好地关闭 PTY。