在python中将标头添加到子进程的stdout
Posted
技术标签:
【中文标题】在python中将标头添加到子进程的stdout【英文标题】:add header to stdout of a subprocess in python 【发布时间】:2018-06-01 18:26:36 【问题描述】:我将几个数据框合并为一个并使用unix sort
对它们进行排序。在我编写最终排序的数据之前,我想为该输出添加一个前缀/标题。
所以,我的代码是这样的:
my_cols = '\t'.join(['CHROM', 'POS', "REF" ....])
my_cmd = ["sort", "-k1,2", "-V", "final_merged.txt"]
with open(output + 'mergedAndSorted.txt', 'w') as sort_data:
sort_data.write(my_cols + '\n')
subprocess.run(my_cmd, stdout=sort_data)
但是,上面的这个 doe 将 my_cols
放在最终输出文件的末尾(即 mergedAndSorted.txt)
我也尝试过替换:
sort_data=io.StringIO(my_cols)
但正如我所料,这给了我一个错误。
如何将该标头添加到子流程输出的开头。我相信这可以通过简单的代码更改来实现。
【问题讨论】:
它做错了什么?在不告诉我们的情况下,我们只能猜测导致它出错的代码出了什么问题。 @abarnert :您可以看到sort_data=io.StringIO .
之一根本不起作用。另一个sort_data.write(my_cols + '\n')
将字符串放在输出文件的末尾,尽管它应该放在开头。
我不知道为什么这个简单明了的问题被投票结束。另外,我在网上搜索了一个多小时以找到解决方案,并尝试了一些代码更改来修复它。为什么人们如此紧张地关闭/否决这个问题,甚至没有完全阅读它。另外,这个问题应该是如此全面和详细。
真的吗?我怎么能看到它不起作用?我无法运行它,因为....
,并且不知道mergedAndSorted.txt
中的内容,即使我可以,它实际上也不会产生任何输出,所以我怎么能看到它正在做的事情有什么问题?您的编辑确实解释了它做错了什么,而不是让我们猜测,这是一个巨大的改进——但它与minimal reproducible example 的距离更远,因为它在output
上添加了一个NameError
。如果您对 cmets 要求您提供缺失信息感到不快,请阅读帮助并首先包含该信息。
至于否决票……老实说,在您解决问题中最严重的问题后,您通常不会让他们回来(因为最初的投票者通常不会回来),但如果您编辑问题变成一个好问题,你通常会得到足够多的支持来弥补它。但是你真的不应该太关注选票;对你来说,你是否得到一个对你有帮助的答案肯定比无意义的上网点更重要?
【参考方案1】:
您的代码的问题是缓冲问题; tldr 是你可以像这样修复它:
sort_data.write(my_cols + '\n')
sort_data.flush()
subprocess.run(my_cmd, stdout=sort_data)
如果您想了解它发生的原因,以及修复如何解决它:
当您以文本模式打开文件时,您打开的是一个缓冲文件。写入进入缓冲区,文件对象不一定立即将它们刷新到磁盘。 (还有从 Unicode 到字节的流编码,但这并没有真正增加新问题,它只是增加了两层可能发生相同事情的地方,所以我们忽略它。)
只要您的所有写入都写入缓冲文件对象,就可以了——它们在缓冲区中被正确排序,因此它们在磁盘上被正确排序。
但如果您写入底层的sort_data.buffer.raw
磁盘文件或sort_data.fileno()
OS 文件描述符,这些写入可能会先于sort_data
的写入。
这正是当您在subprocess
中将文件用作管道时发生的情况。这个好像没有直接解释,但可以从Frequently Used Arguments推断:
stdin、stdout和stderr分别指定执行程序的标准输入、标准输出和标准错误文件句柄。有效值为
PIPE
、DEVNULL
、现有文件描述符(正整数)、现有文件对象和None
。
这非常强烈地暗示——如果你对管道在 *nix 和 Windows 上的工作方式有足够的了解——它将实际的文件描述符/句柄传递给底层的操作系统功能。但实际上并没有这么说。确实,您必须检查the Unix source 和Windows source,您可以看到它在文件对象上调用fileno
或msvcrt.get_osfhandle
。
【讨论】:
以上是关于在python中将标头添加到子进程的stdout的主要内容,如果未能解决你的问题,请参考以下文章