我试图在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”分割代码行的正确方法吗?谢谢。
text
是subprocess.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]
(作为奖励,如果需要,报价会自动处理)