Python Popen - 未知参数:|
Python Popen - Unknown argument: |
我在使用以下脚本时收到 Unknown argument: |
,我不确定为什么它不喜欢 |
。我在 Windows,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)
更新:
使用下面的建议,我现在已经尝试了这个,但我得到 pipe:: Operation not permitted
。我做错了什么?
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()
另一项更新:
因此,使用下面的建议并尝试其他方法,我一直得到相同的结果 pipe:: Operation not permitted
。这是完整的 sdterr
,我还能尝试什么:
"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
更新:
她是 ffmpeg 报告:
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
更新:
使用这段代码,我仍然得到相同的结果 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
更新:
已修复,原来是文件路径权限问题,感谢大家的帮助。
当您将 shell
设置为 False
时,如果 args
(即第一个)参数是字符串,则它应该是程序的名称。否则它应该是一个字符串序列,第一个是程序,其余是参数。
使用管道时 shell 的重要性在于:
VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov
all 不被视为参数。 VSPipe.exe
的参数是 --y4m
和 script.vpy
。 ffmpeg.exe
的参数是 -f
、yuv4mpegpipe
、-i
等。shell 是处理管道的东西——它启动两个程序(提供它们的参数) ,但它首先创建一个管道,以便第一个的 stdout
连接到第二个的 stdin
。
如果您没有支持管道的 shell,您可以在 python 中模拟它,方法是同时启动它们,然后将输出从第一个传输到第二个。
来自子进程 docs:
Use Popen with the communicate() method when you need pipes.
基于@skyking 的回答和您更新的代码,看起来您只需要使用 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 是一个很难在第一次就做好的模块,很高兴看到它在其他项目中使用的可靠示例。
另一个好建议是尽量保持平台无关性。即使您无意 运行 除了 Windows 之外的任何东西,它也会帮助您避免您正在使用的系统的特性。
首先,我建议您在此处为所有 .exe 使用完整路径,这是我以前用来执行此操作的代码。
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
对于Windows:
path = get_locate_command_result(bin_name, which_command="where", default_path=default_path)
所以你可以尝试类似的东西(未测试):
# 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())
我在使用以下脚本时收到 Unknown argument: |
,我不确定为什么它不喜欢 |
。我在 Windows,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)
更新:
使用下面的建议,我现在已经尝试了这个,但我得到 pipe:: Operation not permitted
。我做错了什么?
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()
另一项更新:
因此,使用下面的建议并尝试其他方法,我一直得到相同的结果 pipe:: Operation not permitted
。这是完整的 sdterr
,我还能尝试什么:
"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
更新: 她是 ffmpeg 报告:
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
更新:
使用这段代码,我仍然得到相同的结果 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
更新: 已修复,原来是文件路径权限问题,感谢大家的帮助。
当您将 shell
设置为 False
时,如果 args
(即第一个)参数是字符串,则它应该是程序的名称。否则它应该是一个字符串序列,第一个是程序,其余是参数。
使用管道时 shell 的重要性在于:
VSPipe.exe --y4m script.vpy - | ffmpeg.exe -f yuv4mpegpipe -i - -c:v prores -an output.mov
all 不被视为参数。 VSPipe.exe
的参数是 --y4m
和 script.vpy
。 ffmpeg.exe
的参数是 -f
、yuv4mpegpipe
、-i
等。shell 是处理管道的东西——它启动两个程序(提供它们的参数) ,但它首先创建一个管道,以便第一个的 stdout
连接到第二个的 stdin
。
如果您没有支持管道的 shell,您可以在 python 中模拟它,方法是同时启动它们,然后将输出从第一个传输到第二个。
来自子进程 docs:
Use Popen with the communicate() method when you need pipes.
基于@skyking 的回答和您更新的代码,看起来您只需要使用 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 是一个很难在第一次就做好的模块,很高兴看到它在其他项目中使用的可靠示例。
另一个好建议是尽量保持平台无关性。即使您无意 运行 除了 Windows 之外的任何东西,它也会帮助您避免您正在使用的系统的特性。
首先,我建议您在此处为所有 .exe 使用完整路径,这是我以前用来执行此操作的代码。
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
对于Windows:
path = get_locate_command_result(bin_name, which_command="where", default_path=default_path)
所以你可以尝试类似的东西(未测试):
# 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())