Python:在子进程

时间:2015-08-06 04:32:35

标签: python shell python-3.x subprocess

我对python及其子进程模块非常陌生,但我试图弄清楚如何在子进程中运行命令。具体来说,我在原始命令行界面模式(http://magicseteditor.sourceforge.net/doc/cli/cli)中运行Magic Set Editor 2,我想要一个可以接受它并从中导出一堆图像的脚本。通过交互式CLI在cmd.exe中执行此操作非常简单:

mse --cli setName.mse-set
//entered the interactive CLI now.
> write_image_file(file:set.cards[cardNumber].name+".png", set.cards[cardNumber]

并且写了一个png到我的文件夹,到目前为止一直很好。我可以使用原始命令行执行相同的操作:

mse --cli setName.mse-set --raw
//entered the raw CLI now.
write_image_file(file:set.cards[cardNumber].name+".png", set.cards[cardNumber]
再次,实现了一个png和所有这一切。现在的诀窍是,如何让python脚本做同样的事情?我当前的脚本如下:

import subprocess

s = subprocess.Popen("mse --cli setName.mse-set --raw",shell=True)
s.communicate("write_image_file(file:set.cards[1].name+'.png',set.cards[1]")

我有shell = True,因为在cmd.exe中它似乎打开了一个新shell,但是当我运行这个脚本时它只是打开那个shell并且似乎没有运行第二行,它就在那里等待我的输入,我希望脚本提供。

我找到了另一种方法,但它仍然没有为我点击:

from subprocess import Popen, PIPE

s = Popen("mse --cli setName.mse-set --raw",stdin=PIPE)
s.communicate("write_image_file(file:set.cards[1].name+'.png',set.cards[1]")

...因为我收到了错误:

Traceback (most recent call last):
  File "cardMaker.py", line 6, in <module>
    s.communicate("write_image_file(file:set.cards[1].name+'.png',set.cards[1]")
  File "C:\Python34\lib\subprocess.py", line 941, in communicate
    self.stdin.write(input)
TypeError: 'str' does not support the buffer interface

编辑:在解决了最初的问题后,我还有另一个问题;如何发送多个命令?具有相同命令的另一个s.communicate行失败,错误为:Cannot send input after starting communication

1 个答案:

答案 0 :(得分:2)

来自subprocess -

的文档
  

Popen.communicate(输入=无,超时=无)

     

与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。可选的输入参数应该是要发送到子进程的数据,如果没有数据应该发送给子进程,则应该是None。 输入类型必须为字节,如果universal_newlines为True,则为字符串。

(强调我的)

您需要将一个字节字符串作为输入发送到communicate()方法,例如 -

from subprocess import Popen, PIPE

s = Popen("mse --cli setName.mse-set --raw",stdin=PIPE)
s.communicate(b"write_image_file(file:set.cards[1].name+'.png',set.cards[1]")

此外,您应该发送命令以列表形式运行,示例 -

from subprocess import Popen, PIPE

s = Popen(['mse', '--cli', 'setName.mse-set', '--raw'],stdin=PIPE)
s.communicate(b"write_image_file(file:set.cards[1].name+'.png',set.cards[1]")