Linux:在python脚本中将cat命名为pipe

时间:2015-08-19 16:46:27

标签: python linux pipe subprocess cat

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

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

$ 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

非常感谢一点帮助: - )

1 个答案:

答案 0 :(得分:2)

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

BASH_PIPE_VIDEO = 'cat /dev/video1 > videopipe'

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

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

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

在与“cat to named pipe”问题无关的说明中 - 请确保您的空格正确无误。

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

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

请确保正确拆分参数:

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