简体   繁体   中英

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. 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. Doing this in cmd.exe through the interactive CLI is trivial:

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. 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. Now the trick is, how do I get a python script to do the same thing? 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.

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 .

From the documentation of subprocess -

Popen.communicate(input=None, timeout=None)

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. 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. The type of input must be bytes or, if universal_newlines was True, a string.

(Emphasis mine)

You need to send in a byte-string as input to the communicate() method , 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]")

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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