根据Python 3.5 docs,subprocess.run()返回一个带有stdout成员的CompletedProcess对象,该成员包含“一个字节序列,如果使用universal_newlines = True调用run(),则返回一个字符串。”我只看到一个字节序列而不是字符串,我假设(希望)等同于文本行。例如,
import pprint
import subprocess
my_data = ""
line_count = 0
proc = subprocess.run(
args = [ 'cat', 'input.txt' ],
universal_newlines = True,
stdout = subprocess.PIPE)
for text_line in proc.stdout:
my_data += text_line
line_count += 1
word_file = open('output.txt', 'w')
pprint.pprint(my_data, word_file)
pprint.pprint(line_count, word_file)
注意:这使用了Python 3.5中的新功能,该功能将无法在以前的版本中运行。
我是否需要创建自己的行缓冲逻辑,还是有办法让Python为我做这个?
答案 0 :(得分:9)
proc.stdout
已经是您的案例中的字符串,运行print(type(proc.stdout))
以确保。它包含所有子进程'输出 - subprocess.run()
在子进程死亡之前不会返回。
for text_line in proc.stdout:
不正确:for char in text_string
枚举Python中的字符(Unicode代码点),而不是行。要获得线路,请致电:
lines = result.stdout.splitlines()
如果字符串中有Unicode换行符,则结果可能与.split('\n')
不同。
如果要逐行读取输出(以避免长时间运行的进程耗尽内存):
from subrocess import Popen, PIPE
with Popen(command, stdout=PIPE, universal_newlines=True) as process:
for line in process.stdout:
do_something_with(line)
注意:在这种情况下,process.stdout
是一个类似文件的对象。 Popen()
不等待进程完成 - Popen()
在子进程启动后立即返回。 process
是subprocess.Popen
个实例,而不是CompletedProcess
。
如果您只需要计算输出中的行数(以b'\n'
结尾),例如wc -l
:
from functools import partial
with Popen(command, stdout=PIPE) as process:
read_chunk = partial(process.stdout.read, 1 << 13)
line_count = sum(chunk.count(b'\n') for chunk in iter(read_chunk, b''))
请参阅Why is reading lines from stdin much slower in C++ than Python?
答案 1 :(得分:1)
如果您需要在数组中使用STDOUT行以更好地操作它们,您只需错过通过&#34; Universal换行符&#34;分离器
nmap_out = subprocess.run(args = ['nmap', '-T4', '-A', '192.168.1.128'],
universal_newlines = True,
stdout = subprocess.PIPE)
nmap_lines = nmap_out.stdout.splitlines()
print(nmap_lines)
输出是:
['Starting Nmap 7.01 ( https://nmap.org ) at 2016-02-28 12:24 CET', 'Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn', 'Nmap done: 1 IP address (0 hosts up) scanned in 2.37 seconds']
答案 2 :(得分:0)
您正在看一个字符串,比较:
import subprocess
proc = subprocess.run(
args = [ 'cat', 'input.txt' ],
universal_newlines = False,
stdout = subprocess.PIPE)
print (type(proc.stdout))
class'bytes'
运行电话popen.communicate
communic()返回一个元组(stdout_data,stderr_data)。数据 将是字节,或者,如果universal_newlines为True,则为字符串。
查看here以获取更多解释和其他shell交互。