rey*_*nlp 15 python stdin subprocess stdout pexpect
我需要做这样的帖子,但是我需要创建一个可以给出输入并多次输出的子进程.该帖子的接受答案有良好的代码......
from subprocess import Popen, PIPE, STDOUT
p = Popen(['grep', 'f'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
grep_stdout = p.communicate(input=b'one\ntwo\nthree\nfour\nfive\nsix\n')[0]
print(grep_stdout.decode())
# four
# five
Run Code Online (Sandbox Code Playgroud)
......我想继续这样:
grep_stdout2 = p.communicate(input=b'spam\neggs\nfrench fries\nbacon\nspam\nspam\n')[0]
print(grep_stdout2.decode())
# french fries
Run Code Online (Sandbox Code Playgroud)
但是,我得到以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/subprocess.py", line 928, in communicate
raise ValueError("Cannot send input after starting communication")
ValueError: Cannot send input after starting communication
Run Code Online (Sandbox Code Playgroud)
如果我理解正确的话,proc.stdin.write()方法不能让你收集输出.什么是保持线路开放以进行持续输入/输出的最简单方法?
编辑:====================
它看起来像是pexpect一个有用的库,我正在尝试做什么,但我无法让它工作.这是对我实际任务的更完整的解释.我hfst用来获得个别(俄语)单词的语法分析.以下演示了它在bash shell中的行为:
$ hfst-lookup analyser-gt-desc.hfstol
> ?????
????? ?????+N+Neu+Inan+Sg+Acc 0.000000
????? ?????+N+Neu+Inan+Sg+Nom 0.000000
> ????????
???????? ?????????+V+Perf+IV+Imp+Sg2 0.000000
???????? ?????????+V+Perf+TV+Imp+Sg2 0.000000
>
Run Code Online (Sandbox Code Playgroud)
我希望我的脚本能够一次获得一个表单的分析.我试过像这样的代码,但它不起作用.
import pexpect
analyzer = pexpect.spawnu('hfst-lookup analyser-gt-desc.hfstol')
for newWord in ['?????','????????'] :
print('Trying', newWord, '...')
analyzer.expect('> ')
analyzer.sendline( newWord )
print(analyzer.before)
# trying ????? ...
#
# trying ???????? ...
# ?????
# ????? ?????+N+Neu+Inan+Sg+Acc 0.000000
# ????? ?????+N+Neu+Inan+Sg+Nom 0.000000
#
#
Run Code Online (Sandbox Code Playgroud)
我显然误解了什么pexpect.before.如何获得每个单词的输出,一次一个?
tde*_*ney 20
Popen.communicate()是一个辅助方法,做数据的一次性写入stdin和创建线程从中提取数据stdout和stderr.stdin当它完成写入数据和读取stdout并且stderr直到那些管道关闭时它关闭.你不能做一秒钟,communicate因为孩子在返回时已经退出.
与子进程的交互式会话相当复杂.
一个问题是子进程是否认识到它应该是交互式的.在大多数命令行程序用于交互的C库中,从终端(例如,linux控制台或"pty"伪终端)运行的程序是交互式的并且经常刷新它们的输出,但是通过PIPES从其他程序运行的程序是非互动并不经常刷新他们的输出.
另一个是你应该如何阅读和处理stdout,stderr没有死锁.例如,如果你阻止阅读stdout,但stderr填充它的管道,孩子将停止,你被卡住了.您可以使用线程将两者都拉入内部缓冲区.
另一个是你如何处理一个出乎意料地退出的孩子.
对于像linux和OSX这样的"unixy"系统,pexpect编写该模块是为了处理交互式子进程的复杂性.对于Windows,我知道没有好的工具可以做到这一点.
rey*_*nlp 12
这个答案应该归功于@JFSebastian.感谢您的评论!
以下代码得到了我预期的行为:
import pexpect
analyzer = pexpect.spawnu('hfst-lookup analyser-gt-desc.hfstol')
analyzer.expect('> ')
for word in ['?????', '????????']:
print('Trying', word, '...')
analyzer.sendline(word)
analyzer.expect('> ')
print(analyzer.before)
Run Code Online (Sandbox Code Playgroud)
每当您要将输入发送到流程时,请使用proc.stdin.write()。每当您想从流程中获取输出时,请使用proc.stdout.read()。构造函数的stdin和stdout参数都必须设置为PIPE。
| 归档时间: |
|
| 查看次数: |
14412 次 |
| 最近记录: |