我调用ffmpeg同subprocess.Popen,并试图捕捉stderr输出并将它写入logging.
args = ['ffmpeg', '-i', path]
if start:
args += ['-ss', start]
if end:
args += ['-t', end]
args += [
'-vcodec', 'copy',
'-acodec', 'copy',
'-scodec', 'copy',
'-f', 'mpegts',
'-y', '/dev/stdout']
self.child = subprocess.Popen(
args,
stdin=open(os.devnull, 'rb'),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
ffmpeg 生成大量配置信息,如下所示:
FFmpeg版本0.6.2-4:0.6.2-1ubuntu1,版权所有(c)2000-2010 Libav开发人员于2011年3月22日15:55:04建立了gcc 4.5.2
配置: - extra-version = 4:0.6 .2-1ubuntu1 --prefix =/usr --enable-avfilter --enable-avfilter-lavf --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable -libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --disable-stripping --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc - -enable-swscale …
如果这是我的子流程:
import time, sys
for i in range(200):
sys.stdout.write( 'reading %i\n'%i )
time.sleep(.02)
Run Code Online (Sandbox Code Playgroud)
这是控制和修改子进程输出的脚本:
import subprocess, time, sys
print 'starting'
proc = subprocess.Popen(
'c:/test_apps/testcr.py',
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE )
print 'process created'
while True:
#next_line = proc.communicate()[0]
next_line = proc.stdout.readline()
if next_line == '' and proc.poll() != None:
break
sys.stdout.write(next_line)
sys.stdout.flush()
print 'done'
Run Code Online (Sandbox Code Playgroud)
为什么readline和communicate等待,直到程序完成后运行?有没有一种简单的方法来传递(和修改)子进程'stdout实时?
顺便说一下,我已经看过了,但是我不需要记录功能(并且没有太多的了解它).
我在Windows XP上.
我尝试完成的任务是流式传输ruby文件并打印出输出.(注意:我不想一次打印出所有内容)
main.py
from subprocess import Popen, PIPE, STDOUT
import pty
import os
file_path = '/Users/luciano/Desktop/ruby_sleep.rb'
command = ' '.join(["ruby", file_path])
master, slave = pty.openpty()
proc = Popen(command, bufsize=0, shell=True, stdout=slave, stderr=slave, close_fds=True)
stdout = os.fdopen(master, 'r', 0)
while proc.poll() is None:
data = stdout.readline()
if data != "":
print(data)
else:
break
print("This is never reached!")
Run Code Online (Sandbox Code Playgroud)
ruby_sleep.rb
puts "hello"
sleep 2
puts "goodbye!"
Run Code Online (Sandbox Code Playgroud)
问题
流文件工作正常.hello/goodbye输出以2秒延迟打印.正如脚本应该工作.问题是readline()最后会挂起而永不退出.我从未到过最后一个印刷品.
我知道有很多这样的问题,这里有一个stackoverflow但是没有它们让我解决问题.我不是那个整个子流程的东西,所以请给我一个更实际/具体的答案.
问候
编辑
修复意外的代码.(与实际错误无关)
如何使用python子进程模块复制以下批处理命令?
myprogram < myinput.in > myoutput.out
Run Code Online (Sandbox Code Playgroud)
换句话说,如何myprogram使用myinput.in标准输入和myoutput.out标准输出的内容运行?
我正在编写一个Python程序,用于在Linux服务器上运行用户上传的任意(因此,在最坏的情况下,不安全,错误和崩溃)代码.抛开安全问题,我的目标是确定代码(可能是任何语言,编译或解释)是否写入了正确的内容stdout,stderr以及给定输入的其他文件是否输入到程序中stdin.在此之后,我需要向用户显示结果.
目前,我的解决办法是使用产卵子进程subprocess.Popen(...)与文件句柄stdout,stderr和stdin.后面的文件stdin句柄包含了操作过程中的程序读取输入,并且该程序已终止后,将stdout和stderr文件的读取,并检查正确性.
这种方法非常完美,但是当我显示结果时,我无法组合给定的输入和输出,因此输入将出现在与从终端运行程序时相同的位置.即类似的程序
print "Hello."
name = raw_input("Type your name: ")
print "Nice to meet you, %s!" % (name)
Run Code Online (Sandbox Code Playgroud)
stdout运行后,包含该程序的文件的内容将是:
Hello.
Type your name:
Nice to meet you, Anonymous!
Run Code Online (Sandbox Code Playgroud)
鉴于内容包含该文件stdin是Anonymous<LF>.所以,简而言之,对于给定的示例代码(以及,等效地,对于任何其他代码),我想实现如下结果:
Hello.
Type your name: Anonymous
Nice to meet you, Anonymous!
Run Code Online (Sandbox Code Playgroud)
因此,问题是检测程序何时等待输入.
我尝试了以下方法来解决问题:
这允许父进程沿管道单独发送数据,但只能调用一次,因此不适用于具有多个输出和输入的程序 - 正如可以从文档中推断出来的那样.
我有一些Python代码偶尔需要跨越一个新进程来以"一劳永逸"的方式运行shell脚本,即没有阻塞.shell脚本不会与原始Python代码通信,实际上可能会终止调用Python进程,因此启动的shell脚本不能是调用Python进程的子进程.我需要它作为一个独立的过程启动.
换句话说,假设我有mycode.py并启动script.sh.然后mycode.py将继续处理而不会阻塞.脚本script.sh将独立完成一些操作,然后实际停止并重新启动mycode.py.因此运行script.py的进程必须完全独立于mycode.py.我怎么能这样做?我认为subprocess.Popen不会阻塞,但仍然会创建一个子进程,一旦mycode.py停止就会终止,这不是我想要的.
子进程以#开头
subprocess.Popen(arg)
Run Code Online (Sandbox Code Playgroud)
如果父母异常终止,有没有办法确保它被杀死?我需要这个在Windows和Linux上都可以工作.我知道这个Linux解决方案.
编辑:
subprocess.Popen(arg)如果使用不同的启动流程的方法存在解决方案,则可以放宽启动子流程的要求.
我有一个测试工具(用Python编写),需要通过发送来关闭被测程序(用C语言编写)^C.在Unix上,
proc.send_signal(signal.SIGINT)
Run Code Online (Sandbox Code Playgroud)
工作得很好.在Windows上,会抛出错误("不支持信号2"或类似的东西).我正在使用Python 2.7 for Windows,所以我觉得我应该能够做到
proc.send_signal(signal.CTRL_C_EVENT)
Run Code Online (Sandbox Code Playgroud)
但这根本不起作用.我需要做什么?这是创建子进程的代码:
# Windows needs an extra argument passed to subprocess.Popen,
# but the constant isn't defined on Unix.
try: kwargs['creationflags'] = subprocess.CREATE_NEW_PROCESS_GROUP
except AttributeError: pass
proc = subprocess.Popen(argv,
stdin=open(os.path.devnull, "r"),
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
**kwargs)
Run Code Online (Sandbox Code Playgroud) 我想stdout在python(3)脚本中捕获shell命令的流,并且能够同时检查shell命令的返回代码,如果它返回错误(即,如果它的返回代码是不是0).
subprocess.check_output似乎是这样做的合适方法.来自subprocess的手册页:
check_output(*popenargs, **kwargs)
Run command with arguments and return its output as a byte string.
If the exit code was non-zero it raises a CalledProcessError. The
CalledProcessError object will have the return code in the returncode
attribute and output in the output attribute.
Run Code Online (Sandbox Code Playgroud)
但是,当它失败时,我没有成功从shell命令获取返回码.我的代码看起来像这样:
import subprocess
failing_command=['ls', 'non_existent_dir']
try:
subprocess.check_output(failing_command)
except:
ret = subprocess.CalledProcessError.returncode # <- this seems to be wrong
if ret in (1, 2):
print("the command failed")
elif ret in (3, 4, …Run Code Online (Sandbox Code Playgroud) 在为Android Debug Bridge(ADB)开发python包装器库时,我正在使用子进程在shell中执行adb命令.这是简化的例子:
import subprocess
...
def exec_adb_command(adb_command):
return = subprocess.call(adb_command)
Run Code Online (Sandbox Code Playgroud)
如果命令执行propery exec_adb_command返回0即可.
但是一些adb命令不仅会返回"0"或"1",还会生成一些我想要捕获的输出.adb设备例如:
D:\git\adb-lib\test>adb devices
List of devices attached
07eeb4bb device
Run Code Online (Sandbox Code Playgroud)
我已经为此目的尝试了subprocess.check_output(),它确实返回输出但不返回代码("0"或"1").
理想情况下,我想得到一个元组,其中t [0]是返回码,t [1]是实际输出.
我是否遗漏了子流程模块中已经允许获得此类结果的内容?
谢谢!