运行无限循环并从“外部”获取命令(例如 shell 或其他脚本)

Posted

技术标签:

【中文标题】运行无限循环并从“外部”获取命令(例如 shell 或其他脚本)【英文标题】:Running infinite loop and getting commands from "outside" (e.g. shell or other scripts) 【发布时间】:2019-01-04 00:29:05 【问题描述】:

我正在研究我的 Raspberry Pi,它正在处理一些 WS2812B RGB-LED。我可以使用 neopixel 库和 Python 来控制灯光和一切。现在很好。

我希望这个 Python 脚本运行一个只处理灯光管理的无限循环。调光 LED、改变颜色等等。但是,我希望能够从其他脚本中获取命令。假设我想输入一个会改变颜色的 shell 命令。在我的无限 Python 脚本(LED 处理程序)中,我将能够识别此命令并将颜色或灯光模式柔和地更改为所需的颜色。

一个想法是,如果有新命令,则不断查看文本文件。而且我的 shell 脚本能够将命令行插入到这个文本文件中。

但是你能告诉我,是否有更好的解决方案?

非常感谢。

【问题讨论】:

下面的套接字建议是可行的方法。我唯一要补充的是,如果您不需要从外部接收这些命令(如果是要控制它们的脚本),您可能需要考虑使用 Unix Domain Sockets。 @JohnSzakmeister 随意发布这个作为答案。 【参考方案1】:

一种方法是公开一个 TCP 服务器,然后通过 TCP 与 Python 进程通信。这里有一个关于如何创建 TCP 服务器的简单示例,展示了服务器脚本(运行 LED)和命令脚本:example

【讨论】:

这个很不错。非常感谢。但我有一个问题。在您的示例中,调用“server.accept()”会阻止脚本,直到建立新的客户端连接。但我想让主脚本继续进行。是否有类似函数的返回值指示新数据是否可用?谢谢【参考方案2】:

我建议用你的 python 脚本打开一个端口,让它从那个端口接收命令(网络编程)。虽然这会使您的项目更加复杂,但它是一个非常健壮的实现。

【讨论】:

【参考方案3】:

您可以使用ZeroMQ 并将其托管在本地。它提供bindings for Python。这是一个示例脚本(发送方和接收方):

from threading import Thread
import zmq


class Sender(Thread):
    def run(self):
        context = zmq.Context()
        socket = context.socket(zmq.PUB)
        socket.connect('tcp://127.0.0.1:8000')
        while True:
            socket.send_string(input('Enter command: '))


class Receiver(Thread):
    def run(self):
        context = zmq.Context()
        socket = context.socket(zmq.SUB)
        socket.bind('tcp://127.0.0.1:8000')
        socket.setsockopt(zmq.SUBSCRIBE, b'')
        while True:
            data = socket.recv().decode('ascii')
            print(data)  # Do stuff with data.

接收器是控制 RPi 上的灯的实例,发送器是命令行脚本,让您输入各种命令。一个优点是 ZeroMQ 支持bindings for various programming languages,您还可以通过网络发送/接收命令。

【讨论】:

【参考方案4】:

另一个解决方案是允许来自网络连接的命令。带有“无限循环”的脚本将从套接字读取输入并执行命令。

【讨论】:

以上是关于运行无限循环并从“外部”获取命令(例如 shell 或其他脚本)的主要内容,如果未能解决你的问题,请参考以下文章

从 shell 与正在运行的进程通信

shell 脚本 - 在退出无限循环之前完成迭代

如何从输出到前景的Bash脚本运行无限循环

如何从 shell/shell 脚本获取 sqlplus 命令的输出状态?

C fork循环执行无限命令(urandom / tail在活动文件上)

获取linux帮助命令