我需要在 python 中实现一个过滤器,它从 Linux 命令行字典工具中挑选出特定的输出。我需要:
- 从文件中获取一组单词
- 查找每个单词:1)如果单词不包含,则跳过它; 2) else 如果是动词,则保存定义。
为了测试代码,我写了两个python文件:
# name.py
import sys
while True:
print 'name => Q: what is your name?'
sys.stdout.flush()
name = raw_input()
if name == 'Exit':
break
print 'name => A: your name is ' + name
sys.stdout.flush()
# test.py
import subprocess
child = subprocess.Popen(r'python name.py',
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT,
shell = True)
commandlist = ['Luke\n', 'Mike\n', 'Jonathan\n', 'Exit\n']
for command in commandlist:
child.stdin.write(command)
child.stdin.flush()
output = child.stdout.readline()
print 'From PIPE: ' + output
while child.poll() is None:
print 'NOT POLL: ' + child.stdout.readline()
child.wait()
输出是
From PIPE: name => Q: what is your name?
From PIPE: name => A: your name is Luke
From PIPE: name => Q: what is your name?
From PIPE: name => A: your name is Mike
# these lines need to start with "From PIPE" ...
NOT POLL: name => Q: what is your name?
NOT POLL: name => A: your name is Jonathan
NOT POLL: name => Q: what is your name?
NOT POLL:
稍后的输出是在while
循环而不是for
循环进入test.py
。是什么原因?
由于需求,我需要在每次输入新命令时获取完整的输出。这看起来像是一个对话会话。所以subprocess.communicate()
在那里没用,因为它总是终止当前的子进程。如何落实这一诉求?
基本原因subprocess
坚持你使用.communicate()
是因为否则可能会发生死锁。假设您正在写入进程的标准输入,而进程正在写入其标准输出。如果管道缓冲区已满,写入将被阻塞,直到发生读取为止。然后你们就互相等待,却无法取得任何进展。有几种方法可以解决这个问题:
- 使用单独的线程。将一个分配给 stdin,另一个分配给 stdout。这样,如果一根管道堵塞,您仍然可以维修另一根管道。
- Use
select
在管道上进行多路复用。仅与为您准备好的管道交互。您还应该启用O_NONBLOCK
在管道上使用fcntl
,这样您就不会意外填充缓冲区。正确使用,这将防止管道堵塞,因此不会出现死锁。这在 Windows 下不起作用,因为你只能做select
那里的插座上。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)