简体   繁体   English

Python:在子流程中运行命令

[英]Python: running a command within a subprocess

I'm very new to python and its subprocess module, but I'm trying to figure out how to get a command to run within a subprocess. 我对python及其子进程模块非常陌生,但是我试图弄清楚如何让命令在子进程中运行。 Specifically, I'm running Magic Set Editor 2 in raw commandline interface mode ( http://magicseteditor.sourceforge.net/doc/cli/cli ) and I want a script that can take that and export a bunch of images from it. 具体来说,我正在原始命令行界面模式( http://magicseteditor.sourceforge.net/doc/cli/cli )上运行Magic Set Editor 2,并且我想要一个脚本可以采用该脚本并从中导出一堆图像。 Doing this in cmd.exe through the interactive CLI is trivial: 通过交互式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]

and that writes a png to my folder, so far so good. 到目前为止,将png写入我的文件夹。 I can pull off the same thing with the raw commandline: 我可以使用原始命令行完成同样的事情:

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

again, achieves a png and all that. 再次实现png等。 Now the trick is, how do I get a python script to do the same thing? 现在的诀窍是,如何让python脚本执行相同的操作? My current script looks like: 我当前的脚本如下所示:

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]")

I have shell=True because in cmd.exe it seems to open a new shell, but when I run this script it simply opens that shell and doesn't seem to run the second line, it sits there waiting for my input, which I want the script to provide. 我有shell = True,因为在cmd.exe中它似乎打开了一个新的shell,但是当我运行此脚本时,它只是打开了该shell而似乎没有在运行第二行,它坐在那儿等待我的输入,我想要脚本提供。

I found an alternate method but it still doesn't quite click for me: 我找到了另一种方法,但对我来说仍然点击不起来:

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]")

...because I get the errors: ...因为我得到了错误:

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

edit: After solving the initial problem, I have another question; 编辑:解决了最初的问题后,我还有另一个问题; how do I send it multiple commands? 如何发送多个命令? Another s.communicate line with the same command failed with the error: Cannot send input after starting communication . 另一条使用相同命令的s.communicate行失败并显示以下错误: Cannot send input after starting communication

From the documentation of subprocess - subprocess的文档中-

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

Interact with process: Send data to stdin. 与进程交互:将数据发送到stdin。 Read data from stdout and stderr, until end-of-file is reached. 从stdout和stderr读取数据,直到到达文件末尾。 Wait for process to terminate. 等待进程终止。 The optional input argument should be data to be sent to the child process, or None, if no data should be sent to the child. 可选的输入参数应该是要发送到子进程的数据,如果没有数据应该发送到子进程,则为None。 The type of input must be bytes or, if universal_newlines was True, a string. 输入类型必须为字节,或者,如果universal_newlines为True,则为字符串。

(Emphasis mine) (强调我的)

You need to send in a byte-string as input to the communicate() method , Example - 您需要发送一个字节字符串作为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]")

Also , you should send the command to run as a list , Example - 另外,您应该发送命令以列表形式运行,例如-

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]")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM