繁体   English   中英

在Linux上将终端程序从Bash移动到Python

[英]Moving Terminal Program from Bash to Python on Linux

我正在处理一个工业环境,我必须在现场记录串行设备的读数。 我目前的设置涉及连接到Moxa 5150A或5130串行设备服务器的设备,该服务器通过有线或无线方式连接到我的网络,具体取决于各个设备的位置。 目前,我依赖硬件供应商提供的软件来管理数据收集。 目前的软件基于Windows X86,由于以前的硬件故障,我们购买的新硬件不会给您带来麻烦。 我专门为他们的Linux驱动程序和兼容性选择了Moxa串行服务器。 该设备通过RS-422(4线半双工)7位1级奇数奇偶校验和无流量控制进行通信,除非有要求,否则不发送任何信息。

我正在开发自己的解决方案,将信息存储在数据库(可能是MySQL)中。 在终端通信方面,这是两部分。 我必须发送请求并收到回复。

到目前为止,我已经将串行服务器的Moxa驱动程序安装到我的linux服务器上。 我编写了一个从/ dev / ttyrXX设备读取的bash脚本,解释输入并将信息加载到mysql数据库中。

      while read line
      do
      something something....
      done < /dev/ttyrXX

我仍在制作轻微的脚本错误,例如当设备脱机并且稍后重新联机以及其他此类问题时正确地重新启动,但我的脚本正在阅读并记录我的数据以满足我的需求。

该解决方案依赖于两个因素。

1)Moxa设备支持FIFO并允许同时进行多个连接

2)供应商提供的软件在单独的Windows机器上运行,目前正在提交信息请求。

我需要一起删除基于Windows的软件。 我已经编写并测试了一个脚本,该脚本打印到/ dev / ttyrXX,发出我想要的请求并收到相应的响应,并按照我的第一个脚本记录它们。

     some list of things
     for x in list
     do         
     printf "request" > /dev/ttyrXX
     done

我在供应商提供的软件中遇到的一个主要问题是其硬编码依赖于对每个请求的及时响应。 这会产生许多问题,包括如果设备在不合适的时间停止服务,则会完全冻结窗口并导致崩溃。

我的两个脚本一致地工作,以明显更好的间隔收集数据,并且人为干预很少。

这是我的问题。 我可以在Python中使用什么方法来获得与我的Bash脚本相当的结果?

我无法找到一个与printf或cat等效的Python,它不需要我打开/关闭文件。 此外,我看过的每个终端接口都有内置或必需的等待响应或读取这么长时间才放弃。 我确信那里存在着一些东西,我几乎没有运气找到它。 我承认我是Python的新品牌,并且没有写过几行代码来探索它的能力。

让我非常清楚。 当我写作时(我使用线程或单独的脚本,我不关心),我想写信给我的终端,而不用担心别的什么。 我希望在我的下一篇文章即将到来的时候,在我的终端上无需仔细阅读。 (我不是建议一个永无止境的循环,但我确实需要它只是等待输入)。 我希望/需要我的写作和阅读完全独立于彼此,而不关心对方昨天,现在或下周的工作。

先感谢您。

如果有必要,我将能够提供更详细的代码。但是我觉得我在搜索中更需要方向而不是修复错误。 虽然我仍然完全愿意接受建议并且“不要这样做......因为这......”输入

听起来你想要打开一个文件进行读/写并依次读取每一行。

with open(..., 'r+') as dev:
  for line in dev:
     ...
    print >>dev, 'foo'

扩展伊格纳西奥所说的话。 听起来最简单的解决方案是拥有两个在启动时启动的脚本。

其中一个打开打开tty设备并永远收听它。 这是一个阻止读取。 它继续寻找新的输入线,直到它接收(或到达)EOF。 据推测,在这种情况下永远不会发生这种情况。 它看起来像这样:

# tty reader

def listen_to_device():
    with open('/dev/ttyXX', 'r') as tty:
        for line in tty:
            create_db_record(line)

if __name__ == '__main__':
    listen_to_device()

要实现完全可行的代码,唯一需要实现的是'create_db_record'函数。

第二个脚本可能非常相似。 但也许它会继续在目录中查找包含命令的特定文件。 当它发现任何它一个接一个地将它们发送到tty设备时。

# tty controller

import os
import shutil
import time

def wait_for_commands():
    while True:
        if os.path.exists('/tmp/commands.txt'):
            with open('/tmp/commands.txt', 'r') as c:
                for command in c:
                    send_command(command)
            shutil.move('/tmp/commands.txt', 'tmp/proccesed-' str(datetime.utcnow()))
        time.sleep(1)


def send_command(command):
    with open('/dev/ttyXX', 'w') as tty:
        # maybe do some additional changes to command here?
        tty.write(command)


if __name__ == '__main__':
    wait_for_command()

您可以在send_command函数中添加一些额外的处理代码,以便使command.txt文件中的指令变得非常简单。

我建议pyserial(你可以使用非阻塞),但我不知道它是否正确处理任何非RS232的东西。

我无法找到一个与printf或cat等效的Python,它不需要我打开/关闭文件。

通常,您只需打开文件并调用.write()函数(相当于printf)或.readline()函数。 这有什么问题? 当您使用“cat”或“echo”或来自shell脚本的管道时,这也会在后台打开和关闭文件。 如果你真的需要为某些有线的原因重新打开文件(例如内核驱动程序给出麻烦),那么你可以编写一个python函数来做到这一点。

此外,我看过的每个终端接口都有内置或必需的等待响应或读取这么长时间才放弃。

串行库通常只有读取的超时,而不是写入(但对于写入,内核驱动程序通常有一个缓冲区,我认为,如果写得太快,理论上可能会溢出...)。

我没看到的是这个超时对你来说有什么问题? 如果你可以用两个单独的python程序打开终端,一个执行写操作,另一个执行读操作,你的问题就解决了,对吧?

您应该注意的是,您可以对文件执行阻止或非阻塞I / O. 默认情况下,一切都将被阻止。 您可以使用select()系统调用(也来自Python)来解决线程或单独进程的所有需求。 无论何时可以在不阻塞的情况下读取/写入文件,或者存在异常(例如,设备已经消失),或者存在超时(如果设置了一个),则选择将返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM