我正在运行子进程:
cmd="bin/candc --models models"
subprocess.check_output('{} | tee /dev/stderr'.format( cmd ), shell=True,cwd=os.path.abspath('candc'))
我希望能够插入更多只能由当前运行的子进程识别的命令
请注意,必须有一个cwd=os.path.abspath('candc')
参数,以便从二进制文件夹外部调用子进程,否则它将无法运行。
C&C 是一个NLP库,它实际要做的是解析一个给定的句子。我希望能够将句子传递给子进程。我怎么能这样做?
答案 0 :(得分:3)
我认为你要问的是如何将命令传递给candc
的标准输入,就好像你在命令行上运行命令并在其界面上键入命令一样。
如果您可以将所有命令一次性传递为一个大字符串(可能是由换行符连接),则可以使用input
参数执行此操作,如check_output
文档中的示例所示:
cmd="bin/candc --models models"
commands="""first candc command
second candc command
third candc command
"""
subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'),
input=commands)
如果这是Python 3.x,您还必须使用commands
的编码字节,或添加universal_newlines=True
以使check_output
为您执行此操作。如果您的命令是纯ASCII,前者更容易;只需将该行更改为commands = b"""…
。
如果这是一个足够老的版本(我认为这意味着2.6 / 3.2,但我不确定 - 检查上面链接的文档),input
参数尚不存在。在这种情况下,您有三个选择:
subprocess32
关闭PyPI,后者将较新版本的库向后移植到旧版本的Python。input
参数并自己做同样的事情。Popen.communicate
在input
之前收到check_output
参数,因此,您只需手动创建Popen
并在其上调用communicate
即可。最后一个基本上只是第二个的简单版本...但它更简单。实际上,如果你不需要处理超时和使用输出做一些事情等所有额外的复杂性,它只是一个双线程:
p = subprocess.Popen('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'), stdin=PIPE)
p.communicate(commands)
如果您需要以交互方式发送命令(在发送下一个之前等待一个响应),则check_output
无法执行此操作。它只是Popen
对象周围的便利包装器。您需要明确创建Popen
对象,然后执行p.stdin.write
和p.stdout.read
与之通信。
例如,快速和肮脏的版本可能是:
p = subprocess.Popen('{} | tee /dev/stderr'.format(cmd), shell=True,
cwd=os.path.abspath('candc'),
stdin=PIPE, stdout=PIPE)
for command in commands.splitlines():
p.stdout.readline() # read and ignore a prompt
p.stdin.write(command + '\n')
rc = p.wait()
if rc: raise SomeException() # this is the check in check_output
但是,如果提示超过一行,或者不能保证适合一个缓冲区,那么该代码可以阻止,或者...
一般来说,这可能很难做到。 (Python本身在communicate
函数中没有正确使用它,直到3.2或3.3 ......)特别是如果你不理解文档与阻塞输出管道有什么关系。因此,如果这真的是您所需要的,您可能需要考虑使用第三方库来驱动交互式命令行程序,例如pexpect
,而不是自己动手。