我有一个 shell 命令“fst-mor”。它采用文件形式的参数,例如 NOUN.A,它是一个 lex 文件或其他东西。最终命令:fst-mor NOUN.A
然后它产生以下输出:
analyze>INPUT_A_STRING_HERE
OUTPUT_HERE
现在我想从我的 python 脚本中调用 fst-mor,然后输入字符串并希望在脚本中返回输出。
到目前为止,我有:
import os
print os.system("fst-mor NOUN.A")
您想要捕获另一个命令的输出。为此使用该subprocess
模块。
import subprocess
output = subprocess.check_output('fst-mor', 'NOUN.A')
如果您的命令需要交互式输入,您有两种选择:
使用一个subprocess.Popen()
对象,并将stdin
参数设置为subprocess.PIPE
并将输入写入可用的标准输入管道。对于一个输入参数,这通常就足够了。详细阅读该模块的文档subprocess
,但基本的交互是:
proc = subprocess.Popen(['fst-mor', 'NOUN.A'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output, err = proc.communicate('INPUT_A_STRING_HERE')
使用pexpect
库来驱动进程。这让您可以通过查找模式来创建与子流程的更复杂的交互,这是它生成的输出:
import pexpect
py = pexpect.spawn('fst-mor NOUN.A')
py.expect('analyze>')
py.send('INPUT_A_STRING_HERE')
output = py.read()
py.close()
你可以试试:
from subprocess import Popen, PIPE
p = Popen(["fst-mor", "NOUN.A"], stdin=PIPE, stdout=PIPE)
output = p.communicate("INPUT_A_STRING_HERE")[0]
与另一个进程通信的示例:
pipe = subprocess.Popen(['clisp'],stdin=subprocess.PIPE, stdout=subprocess.PIPE)
(response,err) = pipe.communicate("(+ 1 1)\n(* 2 2)")
#only print the last 6 lines to chop off the REPL intro text.
#Obviously you can do whatever manipulations you feel are necessary
#to correctly grab the input here
print '\n'.join(response.split('\n')[-6:])
请注意,通信将在运行后关闭流,因此您必须提前了解所有命令才能使此方法起作用。似乎 pipe.stdout 在标准输入关闭之前不会刷新?我很好奇是否有办法解决我失踪的问题。