简体   繁体   English

Python-将控制台命令传递给第三方控制台应用程序

[英]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. 我有一个应用程序(叫它abc),它有自己的控制台-该soncole通过CMD像这样运行: abc console console.xml abc console在同一窗口中启动,但是C:\\> ,我只能得到> -休息就像CMD。

I know that i can run cmd commands ie like this: 我知道我可以运行cmd命令,例如:

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. 我试图添加更多命令,以检查尽管“冻结”我是否可以做一些事情,例如导出一些xml,但是什么也没发生。

Is there any way to pass any commands to abc? 有什么办法可以将任何命令传递给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. 但是,如果您将其作为另一个Python程序的子进程运行,并且想要自动化其输入,则必须告诉您的Python代码将其输入到应用程序的stdin通道中。

There are a couple of ways to do that with the subprocess module. subprocess模块有两种方法可以做到这一点。 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() : 假设您只想向应用程序提供一次或一组命令,而无需对以后的输出,定时敏感的动作或用户交互做出反应,则确实可以使用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 ). 请注意,您向input参数传递了一个字符串,该字符串包含您要一次性发送的所有命令,并用换行符分隔(因此\\n )。

You can build that string from a list of commands, if you want: pass_command = '\\n'.join(command_list) + '\\n' 如果需要,可以从命令列表构建该字符串: 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. 如果您需要一种更灵活的方式来将输入提供给应用程序,则可以改用stdin=参数,并向其传递文件对象或文件描述符。 Or rather use Popen() for a more flexible interface. 或更确切地说,使用Popen()获得更灵活的界面。

Also note that check_output() doesn't return a pipe, but a string with all the output. 还要注意, check_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. 因此,您需要确保您的应用程序自行结束(或通过发送使其退出的命令),否则check_output()将永远等待。 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. 如果您不能或不想立即退出,则需要使用更灵活的Popen()接口并根据需要进行写入/读取。

Thanks to Blubberdiblub, i was able to make this: 感谢Blubberdiblub,我能够做到这一点:

    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. 也许它不是完美的,并且更高级的用户可以做得更好,但是通过这种方式,我可以打开abc控制台,并向其中传递一些命令,而不是关闭此控制台。

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

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