bash Python 读写 tty
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20894969/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python reading and writing to tty
提问by aidan.plenert.macdonald
BACKGROUND: If you want, skip to the problem section
背景:如果需要,请跳到问题部分
I am working on a front end for test equipment. The purpose of the front end is to make it easier to write long test scripts. Pretty much just make them more human readable and writable.
我正在研究测试设备的前端。前端的目的是更容易编写长测试脚本。几乎只是使它们更具人类可读性和可写性。
The equipment will be tested using a Prologix GPIB-USB Controller (see prologix.biz). We found a tutorial at http://heliosoph.mit-links.info/gpib-on-debian-linux-the-easy-way/and did all of the steps, and it worked!
设备将使用 Prologix GPIB-USB 控制器进行测试(参见 prologix.biz)。我们在http://heliosoph.mit-links.info/gpib-on-debian-linux-the-easy-way/找到了一个教程,并完成了所有步骤,并且成功了!
As we don't have the test equipment yet, we wanted to write an emulator in Python using openpty. We do have the GPIB-USB Controller, just not what gets connected to that. I got the emulator working as a perfect replacement for the GPIB-USB. This means that I would follow the "GPIB on Debian ..." tutorial (above) and get output that I programmed the emulator to return. The input and output were done in the same manner as the tutorial just reading and writing to/from a pty device (ie /dev/pts/2) instead of the tty (ie /dev/ttyUSB0).
由于我们还没有测试设备,我们想使用 openpty 用 Python 编写一个模拟器。我们确实有 GPIB-USB 控制器,只是没有连接到它。我让模拟器作为 GPIB-USB 的完美替代品工作。这意味着我将遵循“Debian 上的 GPIB ...”教程(上面)并获得我对模拟器进行编程以返回的输出。输入和输出以与教程相同的方式完成,只是读取和写入 pty 设备(即 /dev/pts/2)而不是 tty(即 /dev/ttyUSB0)。
Now that the emulator works, we want to write a front end that can be used to write scripts easily. The goal is to make a kind of macro system that writes a bunch of commands when we call a function.
现在模拟器可以工作了,我们要编写一个可以轻松编写脚本的前端。目标是制作一种宏系统,在我们调用函数时会编写一堆命令。
PROBLEM: exists using both the emulator and the device
问题:同时使用模拟器和设备存在
I am using the following Python functions to read, write, and open the tty/pty devices, but I am not getting the same result that I get if I just use echo and cat in bash.
我正在使用以下 Python 函数来读取、写入和打开 tty/pty 设备,但是我得到的结果与我在 bash 中仅使用 echo 和 cat 所得到的结果不同。
tty = os.open(tty_path, os.O_RDWR)
os.read(tty, 100)
os.write(tty, "++ver")
for example, I would expect the following to be equivalent
例如,我希望以下内容是等效的
$ cat < /dev/pty/2 & # According to the tutorial, this must be run in parallel
$ echo "++ver" > /dev/pty/2
Prologix GPIB Version 1.2.3.4 ...
and
和
tty = os.open("/dev/pyt/2", os.o_RDWR)
os.read(tty, 100) # In separate Thread to be run in parallel
os.write(tty, "++ver") # in main thread
The output is very different, please explain why and how I can fix it.
输出非常不同,请解释原因以及如何修复它。
FULL CODE is here: http://pastebin.com/PWVsMjD7
完整代码在这里:http: //pastebin.com/PWVsMjD7
采纳答案by aidan.plenert.macdonald
Well, I asked too soon. I hope someone benefits from this self answer.
嗯,我问得太早了。我希望有人从这个自我回答中受益。
So this works to read and write from both the emulator and the actual device. I am not exactly sure why, and would appreciate an explanation, but this does work in all of my tests
所以这适用于从模拟器和实际设备读取和写入。我不完全确定原因,并且希望得到解释,但这在我的所有测试中都有效
import serial
class VISA:
def __init__(self, tty_name):
self.ser = serial.Serial()
self.ser.port = tty_name
# If it breaks try the below
#self.serConf() # Uncomment lines here till it works
self.ser.open()
self.ser.flushInput()
self.ser.flushOutput()
self.addr = None
self.setAddress(0)
def cmd(self, cmd_str):
self.ser.write(cmd_str + "\n")
sleep(0.5)
return self.ser.readline()
def serConf(self):
self.ser.baudrate = 9600
self.ser.bytesize = serial.EIGHTBITS
self.ser.parity = serial.PARITY_NONE
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.timeout = 0 # Non-Block reading
self.ser.xonxoff = False # Disable Software Flow Control
self.ser.rtscts = False # Disable (RTS/CTS) flow Control
self.ser.dsrdtr = False # Disable (DSR/DTR) flow Control
self.ser.writeTimeout = 2
def close(self):
self.ser.close()
回答by eugene-bright
You do not actually have to use any special module to read from TTY.
Option O_NOCTTY solved my problems with CDCACM example MCU app.
I'm sure it will work for you (as you work on Linux too).
您实际上不必使用任何特殊模块来读取 TTY。
选项 O_NOCTTY 使用 CDCACM 示例 MCU 应用程序解决了我的问题。
我相信它对你有用(因为你也在 Linux 上工作)。
#!/usr/bin/env python3
import io, os
tty = io.TextIOWrapper(
io.FileIO(
os.open(
"/dev/ttyACM1",
os.O_NOCTTY | os.O_RDWR),
"r+"))
for line in iter(tty.readline, None):
print(line.strip())