python - Linux:cat 到 python 脚本中的命名管道

标签 python linux pipe subprocess cat

我有一个 Java 程序,它使用来自帧采集卡的视频。该程序通过 python launcher.py 启动。

我发现读取视频流的最简单方法是让 Java 在命名管道上读取,这非常有效。所以我的 session 是这样的:

$ mkfifo videopipe
$ cat /dev/video1>videopipe

并在第二个终端中(因为 cat 命令被阻塞):

$ python launcher.py

我想自动化这个过程。不幸的是,结果总是一样的:Java 应用程序启动(通过 java 程序中的 print 语句确认),但随后终端停顿并且没有任何显示,异常或其他。

由于这个过程是手动工作的,我想我在 python 程序中做错了什么。为了简化事情,我隔离了管道部分:

from subprocess import call, Popen, PIPE, check_call

BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d /dev/video1', '-i 2', '--set-standard=4']
BASH_CREATE_FIFO_PIPE = ['mkfifo', 'videopipe']
BASH_PIPE_VIDEO = 'cat /dev/video1>videopipe'

def run():
    try:
        print('running bash commands...')
        call(BASH_SWITCHTO_WINTV)
        call(BASH_CREATE_FIFO_PIPE)
        Popen(['cat', '/dev/video1'], stdout=open('videopipe', 'w'))
    except:
        raise RuntimeError('An error occured while piping the video')

if __name__ == '__main__':
    run()

运行时输出:

running bash commands...     
Failed to open  /dev/video1: No such file or directory

一点帮助将不胜感激:-)

最佳答案

如果您使用 shell=True ,只需传递一个字符串:

BASH_PIPE_VIDEO = 'cat /dev/video1 > videopipe'

目前,cat作为您的脚本传递给 shell,并且 /dev/video>videopipe作为文字参数传递给该 shell——根本不作为脚本文本的一部分进行解析,并且没有任何效果,因为脚本(仅调用 cat)不查看其参数。


或者,为了避免不必要的 shell 使用(因此避免与 shell 相关的错误,例如 shellshock,以及如果您接受来自非硬编码源的任何参数,则潜在的注入(inject)攻击):

Popen(['cat', '/dev/video1'], stdout=open('videopipe, 'w'))

关于与您的“猫到命名管道”问题无关的注释 - 确保您的空格正确。

BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d /dev/video1', ...]

...使用名称 <space>/dev/video1 , 前导空格,作为输入设备;这与运行 v4l2-ctl "-d /dev/video1" 相同在 shell 中,这会导致同样的问题。

确保你正确地拆分了你的论点:

BASH_SWITCHTO_WINTV = ['v4l2-ctl', '-d', '/dev/video1', ...]

关于python - Linux:cat 到 python 脚本中的命名管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32101254/

相关文章:

python - 使用 Mercurial API 获取给定变更集的存储库变更

python - 在 strip 中创建卡的异常

linux(红帽)比较目录并复制不同的文件

在父进程和子进程之间创建管道

无法正确读取管道中的值

python - 使用 BaseHTTPRequestHandler 编写响应正文

Python GraphQL Client - 传递变量时意外的标点符号

linux - Jenkins 和 Sonar - 如何在 Linux 上使用 Sonar Runner(因为它只有一个 .bat 执行器)

linux - 如何通过从 shell 脚本中的文件中读取 ip 地址来构造字符串?

在c中使用fork和pipe后,无法在终端中看到程序的输出