Python子进程;无法读取标准输出

时间:2010-11-30 17:33:59

标签: python subprocess stdout

我有大约500,000多个txt文件,总共大约7 + gig数据。我正在使用python将它们放入sqlite数据库。我正在创建2个表,1。是pK和文件的超链接。 对于另一个表,我使用的是一个由同事在perl中发布的实体提取器。

为了实现这一点,我使用subprocess.Popen()。在这个方法之前,我在循环的每次迭代中都打开了perl,但实际上它很有用。

我需要perl是动态的,我需要能够从它发回数据和第四个并且进程不会终止,直到我告诉它这样做。 perl被修改,所以它perl接受一个文件的完整字符串作为标准输入,并在它得到一个\ n时给我一个标准输出。但我在阅读数据时遇到了麻烦......

如果我使用通信,在我的循环的下一次迭代中,我的子进程终止,我得到一个I / O错误。如果我尝试使用readline()或read(),它会锁定。以下是我正在尝试的不同行为的一些例子。

这使我的系统死机,我需要强制关闭python继续。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE)
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'):
   f = open(infile)
   reportString = f.read()
   f.close()

   reportString = reportString.replace('\n',' ')
   reportString = reportString.replace('\r',' ')
   reportString = reportString +'\n'

   numberExtractor.stdin.write(reportString)
   x = numberExtractor.stdout.read()        #I can not see the STDOUT, python freezes and does not run past here.

   print x

这会取消子进程,并且在循环的下一次迭代中出现I / O错误。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE)
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'):

   f = open(infile)
   reportString = f.read()
   f.close()

   reportString = reportString.replace('\n',' ')
   reportString = reportString.replace('\r',' ')
   reportString = reportString +'\n'
   numberExtractor.stdin.write(reportString)
   x = numberExtractor.communicate()   #Works good, I can see my STDOUT from perl but the process terminates and will not run on the next iteration

   print x

如果我像这样运行它,它会很好地运行所有代码。打印行是',模式'rb'在0x015dbf08>对于我的文件夹中的每个项目。

numberExtractor = subprocess.Popen(["C:\\Perl\\bin\\perl5.10.0.exe","D:\\MyDataExtractor\\extractSerialNumbers.pl"], stdout=subprocess.PIPE, stdin= subprocess.PIPE)
for infile in glob.glob(self.dirfilename + '\\*\\*.txt'):
   f = open(infile)
   reportString = f.read()
   f.close()

   reportString = reportString.replace('\n',' ')
   reportString = reportString.replace('\r',' ')
   reportString = reportString +'\n'

   numberExtractor.stdin.write(reportString)
   x = numberExtractor.stdout                #I can not get the value of the object, but it runs through all my files fine.

   print x

希望我犯的是一个简单的错误,但有一些方法我可以将文件发送到我的perll(stdin),获取stdout,然后重复而不必为我循环中的每个文件重新打开我的子进程吗? / p>

1 个答案:

答案 0 :(得分:2)

考虑使用shell。生活更简单。

perl extractSerialNumbers.pl *.txt | python load_database.py

不要乱用Python启动perl和所有这些。只需从perl中读取结果并在Python中处理这些结果。

由于两个进程同时运行,因此这种方法相当快,并且在没有太多编程的情况下会占用大量CPU资源。

在Python程序(load_database.py)中,您只需使用fileinput模块即可读取stdin上提供的整个文件。

import fileinput
for line in fileinput.input():
    load the row into the database

如果你让shell完成设置管道的繁琐工作,这就是你在Python程序中所需要的一切。