Unknown argument:

I am getting Unknown argument: | when using the below script and I'm not sure why it doesn't like the | . I am on Windows, with Python 2.7.11:

import subprocess
from subprocess import Popen, PIPE, STDOUT
import time

command = 'VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov'

process1 = Popen(command, stderr=PIPE, shell=False)

while True:
    line = process1.stderr.readline().decode('utf-8')
    print line
    time.sleep(2)

UPDATE: Using the suggestion below I have now tried this, but I am getting pipe:: Operation not permitted . What am I doing wrong?

import subprocess
from subprocess import Popen, PIPE, STDOUT
import time

command1 = 'VSPipe.exe --y4m script.vpy -'
command2 = 'ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov'

process1 = Popen(command1, stdout=PIPE)
process2 = Popen(command2, stdin=process1.stdout, stderr=PIPE)

print process2.communicate()

ANOTHER UPDATE: So using the suggestions below, and trying other stuff, I keep getting the same result pipe:: Operation not permitted . Here is the full sdterr , what else can I try:

"F:/ffmpeg/VapourSynth/VSPipe.exe" --y4m "C:/Users/myself/Desktop/script.vpy" - 
"F:/ffmpeg/ffmpeg.exe" -f yuv4mpegpipe -i - -c:v prores -an -y "//192.168.0.100/media/temp/OutMov.mov"
ffmpeg version N-77203-gb8e5b1d Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --arch=x86 --target-os=mingw32 --cross-prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/bin/i686-w64-mingw32- --pkg-config=pkg-config --disable-w32threads --enable-gpl --enable-libsoxr --enable-fontconfig --enable-libass --enable-libutvideo --enable-libbluray --enable-iconv --enable-libtwolame --extra-cflags=-DLIBTWOLAME_STATIC --enable-libzvbi --enable-libcaca --enable-libmodplug --extra-libs=-lstdc++ --extra-libs=-lpng --enable-libvidstab --enable-libx265 --enable-decklink --extra-libs=-loleaut32 --enable-libx264 --enable-libxvid --enable-libmp3lame --enable-version3 --enable-zlib --enable-librtmp --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libopenjpeg --enable-gnutls --enable-libgsm --enable-libfreetype --enable-libopus --enable-frei0r --enable-filter=frei0r --enable-libvo-aacenc --enable-bzlib --enable-libxavs --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-libschroedinger --enable-libvpx --enable-libilbc --enable-libwavpack --enable-libwebp --enable-libgme --enable-dxva2 --enable-libdcadec --enable-avisynth --enable-gray --enable-libopenh264 --extra-libs=-lpsapi --extra-cflags= --enable-static --disable-shared --prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/i686-w64-mingw32 --enable-nonfree --enable-libfdk-aac --disable-libfaac --enable-nvenc --enable-runtime-cpudetect
  libavutil      55. 10.100 / 55. 10.100
  libavcodec     57. 17.100 / 57. 17.100
  libavformat    57. 19.100 / 57. 19.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 20.100 /  6. 20.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
pipe:: Operation not permitted

UPDATE: And her is the ffmpeg report:

F:/ffmpeg/ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an -y //192.168.0.100/media/temp/OutMov.mov -report
ffmpeg version N-77203-gb8e5b1d Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 5.2.0 (GCC)
  configuration: --arch=x86 --target-os=mingw32 --cross-prefix=/Users/myself/Desktop/Download/ffmpeg-windows-build-helpers-master/sandbox/mingw-w64-i686/bin/i686-w64-mingw32- --pkg-config=pkg-config --disable-w32threads --enable-gpl --enable-libsoxr --enable-fontconfig --enable-libass --enable-libutvideo --enable-libbluray --enable-iconv --enable-libtwolame --extra-cflags=-DLIBTWOLAME_STATIC --enable-libzvbi --enable-libcaca --enable-libmodplug --extra-libs=-lstdc++ --extra-libs=-lpng --enable-libvidstab --enable-libx265 --enable-decklink --extra-libs=-loleaut32 --enable-libx264 --enable-libxvid --enable-libmp3lame --enable-version3 --enable-zlib --enable-librtmp --enable-libvorbis --enable-libtheora --enable-libspeex --enable-libopenjpeg --enable-gnutls --enable-libgsm --enable-libfreetype --enable-libopus --enable-frei0r --enable-filter=frei0r --enable-libvo-aacenc --enable-bzlib --enable-libxavs --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libvo-amrwbenc --enable-libschroedinger --enable-li  libavutil      55. 10.100 / 55. 10.100
  libavcodec     57. 17.100 / 57. 17.100
  libavformat    57. 19.100 / 57. 19.100
  libavdevice    57.  0.100 / 57.  0.100
  libavfilter     6. 20.100 /  6. 20.100
  libswscale      4.  0.100 /  4.  0.100
  libswresample   2.  0.101 /  2.  0.101
  libpostproc    54.  0.100 / 54.  0.100
Splitting the commandline.
Reading option '-f' ... matched as option 'f' (force format) with argument 'yuv4mpegpipe'.
Reading option '-i' ... matched as input file with argument '-'.
Reading option '-c:v' ... matched as option 'c' (codec name) with argument 'prores'.
Reading option '-an' ... matched as option 'an' (disable audio) with argument '1'.
Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'.
Reading option '//192.168.0.100/media/temp/OutMov.mov' ... matched as output file.
Reading option '-report' ... matched as option 'report' (generate a report) with argument '1'.
Finished splitting the commandline.
Parsing a group of options: global .
Applying option y (overwrite output files) with argument 1.
Applying option report (generate a report) with argument 1.
Successfully parsed a group of options.
Parsing a group of options: input file -.
Applying option f (force format) with argument yuv4mpegpipe.
Successfully parsed a group of options.
Opening an input file: -.
[AVIOContext @ 006d9800] Statistics: 0 bytes read, 0 seeks
pipe:: Operation not permitted

UPDATE: Using this code, I still get the same result pipe:: Operation not permitted :

import subprocess
import os
from subprocess import Popen, PIPE, STDOUT
import shlex

VsPipe = 'F:/ffmpeg/VapourSynth/VSPipe.exe'
vpyScript = 'C:/Users/myself/Desktop/Boychoir-preview_SMALL_JobID_189.vpy'
ffmpeg = 'F:/ffmpeg/ffmpeg.exe'
outputPath = '//192.168.0.100/media/temp/OutMov.mov'

command1 = shlex.split('"%s" --y4m "%s" - ' % (VsPipe, vpyScript))
command2 = shlex.split('"%s" -f yuv4mpegpipe -i - -c:v prores -an -y "%s" -report' % (ffmpeg, outputPath))

process1 = subprocess.Popen(command1, stdout=subprocess.PIPE)
ls_out, _ = process1.communicate()
process2 = subprocess.Popen(command2, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

grep_out, grep_err = process2.communicate(input=ls_out)
print grep_err

UPDATE: Fixed, turned out to be a file path permissions issue, thanks for all the help.


When you set shell to False the args (ie the first) argument is supposed to be the name of a program if it's a string. Otherwise it's supposed to be aa sequence of strings, the first being the program and the rest being the arguments.

The importance of a shell when using pipes is that in the line:

VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov

all is not considered arguments. The arguments to VSPipe.exe are --y4m and script.vpy . The arguments to ffmpeg.exe are -f , yuv4mpegpipe , -i etc. The shell is whats handling the pipe - it starts both programs (with their arguments supplied), but it does so by first creating a pipe so that stdout from the first becomes connected to stdin of the second.

If you don't have a shell that supports piping you could emulate that in python by starting them both and then transport output from the first to the second.


First I would recommand you to user full path for all .exe here a code I used to use to do that.

import os
import re
import subprocess
from subprocess import Popen, PIPE, STDOUT
import shlex

def _get_locate_command_result(bin_name,
                               which_command="which", default_path=""):
    # check_output returns bytes for python3 and str for py2
    try:
        result_locate = subprocess.check_output(
            shlex.split("%s %s" % (which_command, bin_name)), env=os.environ)
        result_locate_table = re.split(r"r?n", result_locate.decode())
        try:
            bin_path = result_locate_table[0].strip()
        except IndexError:
            bin_path = bin_name
        return bin_path


    except subprocess.CalledProcessError:
        return default_path

For Windows:

path = get_locate_command_result(bin_name, which_command="where", default_path=default_path)

So you could try something like that (not tested):

# use "" beacause of ''
command1 = ('"%s" --y4m script.vpy -'
            % _get_locate_command_result("VSPipe.exe", "where", "VSPipe.exe"))
command2 = ('"%s" -f yuv4mpegpipe -i - -c:v prores -an output.mov'
            % _get_locate_command_result("VSPipe.exe", "where", "ffmpeg.exe"))

# Popen needs sequence of string
cmd1 = shlex.split(command1)
cmd2 = shlex.split(command2)

process1 = Popen(cmd1, stdout=PIPE)
process2 = Popen(cmd2, stdin=process1.stdout, stderr=PIPE)

print(process2.communicate())

From the subprocess docs:

Use Popen with the communicate() method when you need pipes.

Building on @skyking's answer and your updated code, it looks like you just need to use communicate():

# Simple Windows script to confirm existence of Desktop directory in users home space
# ls -al | grep Desktop
# This requires Windows Git to be installed for unix utils like ls, grep

# NOTE: you may have problems with this if you're using built in Windows shell
# utilities like dir etc.. This is because these are built into the shell and
# aren't executables on your path. Use shell=True if you have to use these.

import os
import subprocess

# Change to home directory
os.chdir(os.path.expanduser("~"))

# Command parameters sent to Popen initializer should be lists
# Here we are only interested in the output so PIPE stdout
ls_process = subprocess.Popen(['ls', '-al'], stdout=subprocess.PIPE)

# When working with subprocess PIPE we need to use the communicate() method
# We're only interested in stdout so _ is used to throw away stderr (which will be
# None anyway since we didn't pipe stderr)
ls_out, _ = ls_process.communicate()

# We then create our second process but this time we're interested in piping the
# first command into stdin, using stdout and potentially stderr if there was a problem
grep_process = subprocess.Popen(['grep', 'Desktop'],
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)

# We use communicate() again but this time we give the output string of the first command
# as a parameter to communicate()
grep_out, grep_err = grep_process.communicate(input=ls_out)

print grep_out

Subprocess is a difficult module to get right first time and it's great to look at solid examples of it in use in other projects.

Another good tip is to try and keep things as platform independent as possible. Even if you have no intention to run this on anything other than Windows it will help you avoid the idiosyncrasies of the system you're working on.

链接地址: http://www.djcxy.com/p/77096.html

上一篇: 在python子流程中的子shell

下一篇: 未知参数: