我有点想了解解决这个简单问题的python方法是什么。
我的问题很简单。如果使用以下代码,它将挂起。子流程模块doc中对此进行了详细记录。
import subprocess
proc = subprocess.Popen(['cat','-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
for i in range(100000):
proc.stdin.write('%d\n' % i)
output = proc.communicate()[0]
print output
搜索一个解决方案(有一个非常有见地的线程,但是我现在已经迷失了),我发现这个解决方案(以及其他)使用了一个显式的fork:
import os
import sys
from subprocess import Popen, PIPE
def produce(to_sed):
for i in range(100000):
to_sed.write("%d\n" % i)
to_sed.flush()
#this would happen implicitly, anyway, but is here for the example
to_sed.close()
def consume(from_sed):
while 1:
res = from_sed.readline()
if not res:
sys.exit(0)
#sys.exit(proc.poll())
print 'received: ', [res]
def main():
proc = Popen(['cat','-'],stdin=PIPE,stdout=PIPE)
to_sed = proc.stdin
from_sed = proc.stdout
pid = os.fork()
if pid == 0 :
from_sed.close()
produce(to_sed)
return
else :
to_sed.close()
consume(from_sed)
if __name__ == '__main__':
main()
尽管此解决方案在概念上非常容易理解,但它使用了一个以上的进程,并且与子进程模块相比,其停留在太低的级别(那只是为了隐藏此类事情…)。
我想知道:是否有一个简单而干净的解决方案使用了不会挂起的子流程模块,或者要实现此模式,我必须退后一步并实现一个老式的select循环或显式fork?
谢谢
如果需要纯Python解决方案,则需要将读取器或写入器放在单独的线程中。该threading
软件包是一种轻量级的方法,可以方便地访问常见对象并且不会造成混乱。
import subprocess
import threading
import sys
proc = subprocess.Popen(['cat','-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
def writer():
for i in range(100000):
proc.stdin.write(b'%d\n' % i)
proc.stdin.close()
thread = threading.Thread(target=writer)
thread.start()
for line in proc.stdout:
sys.stdout.write(line.decode())
thread.join()
proc.wait()
看到subprocess
现代化的模块以支持流和协程可能会很整洁,这将允许混合使用Python片段和Shell片段的管道更优雅地构建。
问题内容: 我在完全冻结JVM的应用程序中发现一个错误。产生的stacktrace将为开发人员提供有价值的信息,我想从Java控制台中检索它。JVM崩溃时,控制台被冻结,我无法再复制包含的文本。 是否可以将Java控制台直接通过管道传输到文件,或通过其他某种方式访问Java应用程序的控制台输出? 更新:我忘记提了,没有更改代码。我是手动测试仪。 更新2:这是在Windows XP下,它实际上是
问题内容: 如何使用模块执行以下shell命令? 输入数据将来自字符串,因此我实际上并不需要echo。我已经走了这么远,还有谁能解释我也可以通过它进行管道传输sort吗? 更新:请注意,尽管下面接受的答案实际上并没有回答所提出的问题,但我相信S.Lott是正确的,最好避免首先解决该问题! 问题答案: 您将对以下内容感到满意。 将部分工作委托给外壳。让它通过管道连接两个进程。 您将更高兴地将重写为P
问题内容: 我想在我的ipython Notebook中运行bash脚本,并将输出另存为python变量中的字符串,以进行进一步操作。基本上,我想将bash magic的输出传递给一个变量,例如,类似这样的输出: 问题答案: 怎么使用这个: 而不是魔术?使用该符号将以下命令作为shell命令运行,结果全部存储在中。要运行多个命令并收集所有命令的输出,只需组合一个快速的shell脚本即可。
问题内容: 有没有一种方法可以检测go中的命令是否通过管道传输? 例: 我正在从Stdin阅读。 问题答案: 您可以使用进行此操作。 (改编自https://www.socketloop.com/tutorials/golang-check-if-os-stdin-input-data- is-piped-or-from-terminal )
我目前正在使用一个名为s3-upload-stream的Node.js插件,将非常大的文件传输到Amazon S3。它使用multipart API,并且在很大程度上工作得很好。 是否有一种方法可以使aws-sdk成为我可以将流管道传输到的东西?
问题内容: 我有一些Python代码可以执行一个外部应用程序,当该应用程序的输出量很少时,它可以很好地运行,但是在有大量输出时,它会挂起。我的代码如下: 文档中有一些注释似乎表明了潜在的问题。等待中,有: 警告:如果子进程向或管道生成足够的输出,从而阻塞等待OS管道缓冲区接受更多数据的输出,则将死锁。使用避免这种情况。 尽管进行了交流,但我发现: 注意读取的数据缓存在内存中,因此,如果数据大小很大