简体   繁体   English

subprocess.Popen() 将标准输出写入日志文件

[英]subprocess.Popen() write stdout to logfile

I am using the following command to redirect ffmpeg output to terminal and text file.我正在使用以下命令将ffmpeg输出重定向到终端和文本文件。

p1 = subprocess.Popen (['ffmpeg', 'some_ffmpeg_command', '-f', 'mpegts', 'outfile.ts'], stdout=subprocess.PIPE, stderr=STDOUT, universal_newlines=True)
for line in p1.stdout:
    sys.stdout.write(line)
    logfile.write(line)
p1.stdout.close()
p1.wait()

The code works fine until a scenario where manual intervention is required.代码工作正常,直到需要手动干预的场景。 For example, if the file outfile.ts already exists, then the following dialogue is not displayed in console, File 'Desktop/mytestfolder/outfile.ts' already exists. Overwrite ? [y/N]例如,如果文件 outfile.ts 已经存在,那么在控制台中不会显示以下对话框, File 'Desktop/mytestfolder/outfile.ts' already exists. Overwrite ? [y/N] File 'Desktop/mytestfolder/outfile.ts' already exists. Overwrite ? [y/N]

Any idea what's wrong with the above please?知道上面有什么问题吗?

您需要包含-y标志以强制是响应,因为您不能依赖用户交互。

problem is that this prompt doesn't end with a \\n so python read line method waits for it before fetching the whole line.问题是这个提示没有以\\n结尾,所以 python read line 方法在获取整行之前等待它。

The workaround is to read the input character by character.解决方法是逐个字符读取输入。 For instance like this:例如像这样:

current_line = []
while True:
   c = p1.stdout.read(1).decode()
   if not c:
      break
   current_line.append(c)
   # here you can test if the last character is "]" to avoid creating a partial line everytime
   if c == ']':
      partial_line = ''.join(current_line)
      if partial_line.endswith("Overwrite ? [y/N]"):
         # do something, for instance, print it
         print("PROMPT: {}\n".format(partial_line))
   elif c == '\n':
      # full line: print it
      line = ''.join(current_line)
      # reset the current line buffer
      current_line = []
      # and write the line
      sys.stdout.write(line)
      logfile.write(line)

Of course, without answering, the process is going to be blocked.当然,不回答,进程就会被阻塞。 So Popen needs stdin=subprocess.PIPE too, so you can use p1.stdin.write("Y\\n") to reply to the prompt, (or "N\\n" depending on the question).所以Popen需要stdin=subprocess.PIPE p1.stdin.write("Y\\n") ,所以你可以使用p1.stdin.write("Y\\n")来回复提示,(或"N\\n"取决于问题)。

You have to pass y into STDIN.您必须将y传递给 STDIN。

Solution with Popen:使用 Popen 的解决方案:

from subprocess import Popen, PIPE

foo_proc = Popen(['foo', 'bar'], stdin=PIPE, stdout=PIPE)
yes_proc = Popen(['y'], stdout=foo_proc.stdin)
foo_output = foo_proc.communicate()[0]
yes_proc.wait()

Solution with STDIN writing: STDIN 写入的解决方案:

foo_proc = Popen(['foo', 'bar'], stdin=PIPE, stdout=PIPE)
sp.stdin.write("y\n")  # "\n" is important!
foo_output = foo_proc.communicate()[0]
yes_proc.wait()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM