简体   繁体   中英

Python - pass console command to 3rd party console application

i have a question, but it is difficult to explain for me:

I have a application (let call it abc), that have their own console - this soncole runs via CMD like this: abc console console.xml abc console start in the same window, but instead C:\\> , i get only > - rest is like CMD.

I know that i can run cmd commands ie like this:

self.full_path = 'dir /b'
self.pipe = check_output(self.full_path, shell=True, universal_newlines=True).strip()

but, when i try to do that:

self.full_path = 'abc console console.xml'
self.pipe = check_output(self.full_path, shell=True, universal_newlines=True).strip()

nothing has happen, console freeze. I've tried to add some more commands, to check if despite "freeze" i can do something, like export some xml, but nothing happends.

Is there any way to pass any commands to abc?

If your application is sufficiently simple, it will likely accept commands through its standard input. If you run it directly in the shell, it gets its standard input directly from input you provide yourself (unless you use redirection).

But if you run it as a subprocess from another Python program and you want to automate its input, you have to tell your Python code to feed that input into the application's stdin channel.

There are a couple of ways to do that with the subprocess module. Assuming you want to provide a single or a group of commands to your application only once, without reacting on later output, timing sensitive actions or user interaction, you can indeed use check_output() :

import subprocess

external_command = 'abc console console.xml'
pass_command = 'twiddle knob\n'

output = subprocess.check_output(external_command, shell=True,
                                 universal_newlines=True,
                                 input=pass_command)

Note that you pass a string to the input parameter that includes all the commands you want to send in one go, delimited by newlines (hence the \\n ).

You can build that string from a list of commands, if you want: pass_command = '\\n'.join(command_list) + '\\n'

If you need a more flexible way of feeding input into your application, you can use the stdin= parameter instead and pass it a file object or file descriptor. Or rather use Popen() for a more flexible interface.

Also note that check_output() doesn't return a pipe, but a string with all the output. So you need to make sure that your application ends by itself (or by sending it a command that makes it quit), otherwise check_output() will wait forever. If you cannot or don't want to make it quit immediately, you need to use the more flexible Popen() interface and write / read as required.

Thanks to Blubberdiblub, i was able to make this:

    print("\nStarting ABC console")
    self.pass_start = Popen(self.run_abc, shell=True, cwd=self.full_path, stdin=PIPE, universal_newlines=True)
    sleep(20) #becouse consol starts about 15 seconds

    print("\nExport application")
    self.pass_start.stdin.write(self.export_app)
    sleep(2)

    self.pass_start.kill()

Mayby it is not perfect, and more advanced users could do that better, but in this way i'm able to open abc console, and pass there few commands, than close this console.

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