子进程python读取输出

问题描述 投票:1回答:1

我试图在python中使用子进程运行命令并尝试读取它的输出并将其复制到文件中。我的代码是:

    command = "%s -sK:\\run_one_test.csh %s %s" % (PATH, file, VERSION)
    p = subprocess.Popen(command,stdout=subprocess.PIPE)

    text = p.communicate()[0]
    return_code = p.returncode




    with open("%s/%s%s" % (LOG_DIR, file, LOG_EXT), "w") as f:


        f.writelines([l.decode for l in text.split('\n')])

        f.close()

但是,当我使用splitlines时,我收到错误消息:

    f.writelines([l.decode for l in text.split('\n')])
TypeError: a bytes-like object is required, not 'str'

为什么会这样?我用过解码。另外,这是使用“\ n”分割代码行的正确方法吗?谢谢。

python
1个回答
1
投票

textsubprocess.Popen的结果,在python 3中,这是一个bytes对象。你不能使用字符串拆分它(text.split(b"\n")会工作,但你的代码中有更多的问题,所以忘了它)。

然后,你不是在调用decode(缺少括号)。在decode上调用text会起作用:text.decode()

现在使用split('\n'),你将删除行的结尾,这样就无法正常工作(单行文件,ouch)。你需要:

f.writelines(text.decode().splitlines(True))

True参数告诉函数保持行结束的字符)

但毕竟为什么要拆分再次写行?,只需将文件转储为bytes,而不进行后期处理:

with open("%s/%s%s" % (LOG_DIR, file, LOG_EXT), "wb") as f:
    f.write(text)

但为什么要存储输出以将其写回文件呢?只需将文件句柄传递给subprocess.call

with open("%s/%s%s" % (LOG_DIR, file, LOG_EXT), "wb") as f:
   retcode = subprocess.call(command,stdout=f)

或者,如果命令returncode不为0,则强制执行异常:

   subprocess.check_call(command,stdout=f)

因此,如果您要对行进行后处理,对缓冲区进行后处理,或者根本不进行后处理,则可以选择上述3个(可能已修改的)解决方案中的一个。

旁注:不要将命令组成字符串,只需传递参数:

command = "%s -sK:\\run_one_test.csh %s %s" % (PATH, file, VERSION)

变为:

command = [PATH,"-sK:\\run_one_test.csh",file,VERSION]

(作为奖励,如果需要,报价会自动处理)

© www.soinside.com 2019 - 2024. All rights reserved.