subprocess.run()中的CompletedProcess不返回字符串

时间:2015-12-04 23:42:07

标签: python subprocess python-3.5

根据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为我做这个?

3 个答案:

答案 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()在子进程启动后立即返回。 processsubprocess.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交互。