我在 Python 中看不到子进程的输出
I can't see the output of a subprocess in Python
我正在制作一个与 Sphinx-Quickstart 交互的程序。所以我想做的是我的程序识别单词 "path" 然后输入一个特定的值。与其他情况相同,当我没有特定单词时,只需输入回车('\n')。我这样做是因为 Sphinx 有时会改变问题的顺序,如果我使用交流,它们可能会失败。
我在想这样的事情:
import subprocess
from subprocess import PIPE
p = subprocess.Popen('sphinx-quickstart', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=PIPE, shell=True, bufsize=0)
p.stdin.write('doc\n')
a=p.stdout.readline()
print a.read()
while out:
line = out
line = line.rstrip("\n")
if "autodoc" in line:
pr = 1
p.stdin.write('y\n')
out = p.stdout.readline()
continue
if "source and build" in line:
pr = 2
p.stdin.write('y\n')
out = p.stdout.readline()
continue
out = p.stdout.readline()
p.stdin.close()
p.wait()
当我尝试读取输出时我的程序挂起。
感谢您的提问
不确定您想要什么,但这将 运行 并寻找正确的子字符串:
from subprocess import PIPE,Popen,STDOUT
p = Popen('sphinx-quickstart', stdout=PIPE, stderr=STDOUT, stdin=PIPE, universal_newlines=True)
p.stdin.write('doc\n')
for line in iter(p.stdout.readline, ""):
print(line.rstrip())
if "autodoc" in line:
pr = 1
p.stdin.write('y\n')
elif '"source" and "build"' in line:
pr = 2
p.stdin.write('y\n')
当您 运行 代码时,您会看到输出、源代码和构建都包含在引号中,因此您的 if 永远不会起作用。
for line in iter(p.stdout.readline, "")
将实时读取输出以替换您的 while 循环。
输出:
Welcome to the Sphinx 1.2.2 quickstart utility.
Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).
Enter the root path for documentation.
> Root path for the documentation [.]:
You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]:
Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
您看不到输出,因为您已经重定向了子进程的两个 stdout/stderr。
您的程序挂起,因为 sphinx-quickstart
等待您提供一些输入,例如,传递换行符以接受默认值,或者如果没有默认值则输入一些内容,例如项目名称、作者值。
另一个原因是:
后没有换行,sphinx-quickstart
在stdout重定向时不会及时刷新提示
修复它:一次读取一个字符而不是逐行读取,运行 python
使用 -u
选项(或使用 PYTHONUNBUFFERED
envvar)来禁用缓冲。
每次在输出中看到提示行(以 ':'
字符结尾)时,请确保您的脚本提供了有效的输入:
#!/usr/bin/env python
from __future__ import print_function
import os
from subprocess import Popen, PIPE, CalledProcessError
answers = {
'Root path': 'doc',
'source and build': 'y',
'autodoc': 'y',
'Project name': '<Project name>',
'Author name': '<author>',
'Project version': '<version>',
}
def iter_chunks(pipe, terminator_char):
"""Yield chunks from *pipe* that end with *terminator_char*."""
buf = []
for char in iter(lambda: pipe.read(1), ''):
buf.append(char)
if char == terminator_char:
yield ''.join(buf)
del buf[:]
if buf: # last chunk
yield ''.join(buf)
cmd = ['sphinx-quickstart']
p = Popen(cmd, stdin=PIPE, stdout=PIPE, universal_newlines=True, bufsize=0,
env=dict(os.environ, PYTHONUNBUFFERED='1'))
with p.stdin, p.stdout: # close pipes at the end
for chunk in iter_chunks(p.stdout, ':'):
line = chunk.rpartition('\n')[-1] # get last line
if line.lstrip().startswith('>') and line.endswith(':'): # found prompt
answer = next((a for q, a in answers.items() if q in line), '')
print(answer, file=p.stdin) #NOTE: short write is possible
if p.wait() != 0: # raise on non-zero exit status
raise CalledProcessError(p.returncode, cmd)
注意:stderr
未重定向
您还可以使用 pexpect
模块与外部命令进行类似对话的交互,example。
我正在制作一个与 Sphinx-Quickstart 交互的程序。所以我想做的是我的程序识别单词 "path" 然后输入一个特定的值。与其他情况相同,当我没有特定单词时,只需输入回车('\n')。我这样做是因为 Sphinx 有时会改变问题的顺序,如果我使用交流,它们可能会失败。
我在想这样的事情:
import subprocess
from subprocess import PIPE
p = subprocess.Popen('sphinx-quickstart', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=PIPE, shell=True, bufsize=0)
p.stdin.write('doc\n')
a=p.stdout.readline()
print a.read()
while out:
line = out
line = line.rstrip("\n")
if "autodoc" in line:
pr = 1
p.stdin.write('y\n')
out = p.stdout.readline()
continue
if "source and build" in line:
pr = 2
p.stdin.write('y\n')
out = p.stdout.readline()
continue
out = p.stdout.readline()
p.stdin.close()
p.wait()
当我尝试读取输出时我的程序挂起。
感谢您的提问
不确定您想要什么,但这将 运行 并寻找正确的子字符串:
from subprocess import PIPE,Popen,STDOUT
p = Popen('sphinx-quickstart', stdout=PIPE, stderr=STDOUT, stdin=PIPE, universal_newlines=True)
p.stdin.write('doc\n')
for line in iter(p.stdout.readline, ""):
print(line.rstrip())
if "autodoc" in line:
pr = 1
p.stdin.write('y\n')
elif '"source" and "build"' in line:
pr = 2
p.stdin.write('y\n')
当您 运行 代码时,您会看到输出、源代码和构建都包含在引号中,因此您的 if 永远不会起作用。
for line in iter(p.stdout.readline, "")
将实时读取输出以替换您的 while 循环。
输出:
Welcome to the Sphinx 1.2.2 quickstart utility.
Please enter values for the following settings (just press Enter to
accept a default value, if one is given in brackets).
Enter the root path for documentation.
> Root path for the documentation [.]:
You have two options for placing the build directory for Sphinx output.
Either, you use a directory "_build" within the root path, or you separate
"source" and "build" directories within the root path.
> Separate source and build directories (y/n) [n]:
Inside the root directory, two more directories will be created; "_templates"
for custom HTML templates and "_static" for custom stylesheets and other static
files. You can enter another prefix (such as ".") to replace the underscore.
您看不到输出,因为您已经重定向了子进程的两个 stdout/stderr。
您的程序挂起,因为 sphinx-quickstart
等待您提供一些输入,例如,传递换行符以接受默认值,或者如果没有默认值则输入一些内容,例如项目名称、作者值。
另一个原因是:
后没有换行,sphinx-quickstart
在stdout重定向时不会及时刷新提示
修复它:一次读取一个字符而不是逐行读取,运行 python
使用 -u
选项(或使用 PYTHONUNBUFFERED
envvar)来禁用缓冲。
每次在输出中看到提示行(以 ':'
字符结尾)时,请确保您的脚本提供了有效的输入:
#!/usr/bin/env python
from __future__ import print_function
import os
from subprocess import Popen, PIPE, CalledProcessError
answers = {
'Root path': 'doc',
'source and build': 'y',
'autodoc': 'y',
'Project name': '<Project name>',
'Author name': '<author>',
'Project version': '<version>',
}
def iter_chunks(pipe, terminator_char):
"""Yield chunks from *pipe* that end with *terminator_char*."""
buf = []
for char in iter(lambda: pipe.read(1), ''):
buf.append(char)
if char == terminator_char:
yield ''.join(buf)
del buf[:]
if buf: # last chunk
yield ''.join(buf)
cmd = ['sphinx-quickstart']
p = Popen(cmd, stdin=PIPE, stdout=PIPE, universal_newlines=True, bufsize=0,
env=dict(os.environ, PYTHONUNBUFFERED='1'))
with p.stdin, p.stdout: # close pipes at the end
for chunk in iter_chunks(p.stdout, ':'):
line = chunk.rpartition('\n')[-1] # get last line
if line.lstrip().startswith('>') and line.endswith(':'): # found prompt
answer = next((a for q, a in answers.items() if q in line), '')
print(answer, file=p.stdin) #NOTE: short write is possible
if p.wait() != 0: # raise on non-zero exit status
raise CalledProcessError(p.returncode, cmd)
注意:stderr
未重定向
您还可以使用 pexpect
模块与外部命令进行类似对话的交互,example。