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

时间:2017-01-20 11:55:07

标签: python cmd subprocess console-application

我有一个问题,但很难向我解释:

我有一个应用程序(让它称之为abc),它有自己的控制台 - 这个soncole通过CMD运行,如下所示:     abc console console.xml abc控制台在同一个窗口中启动,而是C:\>,我只得到> - 休息就像CMD。

我知道我可以运行cmd命令,如下所示:

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

但是,当我尝试这样做时:

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

没有任何事情发生,控制台冻结。我已经尝试添加更多命令,以检查是否"冻结"我可以做点什么,比如导出一些xml,但没有任何事情发生。

有没有办法将任何命令传递给abc?

2 个答案:

答案 0 :(得分:1)

如果您的应用程序足够简单,它可能会通过其标准输入接受命令。如果直接在shell中运行它,它会直接从您自己提供的输入中获取其标准输入(除非您使用重定向)。

但是如果你从另一个Python程序中将它作为子进程运行并且你想自动化它的输入,你必须告诉你的Python代码将该输入提供给应用程序的stdin通道。

使用subprocess模块有两种方法可以做到这一点。假设您只想为应用程序提供一个或一组命令,而不对后期输出,时间敏感操作或用户交互作出反应,您确实可以使用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)

请注意,您将一个字符串传递给input参数,该参数包含您要一次发送的所有命令,由换行符分隔(因此\n)。

如果需要,您可以从命令列表构建该字符串:pass_command = '\n'.join(command_list) + '\n'

如果您需要更灵活的方式将输入提供给应用程序,则可以使用stdin=参数,并将其传递给文件对象或文件描述符。或者更确切地说使用Popen()来获得更灵活的界面。

另请注意,check_output()不会返回管道,而是返回包含所有输出的字符串。因此,您需要确保应用程序自行结束(或通过向其发送使其退出的命令),否则check_output()将永远等待。如果您不能或不想立即退出,则需要使用更灵活的Popen()接口并根据需要进行写入/读取。

答案 1 :(得分:1)

感谢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它并不完美,更高级的用户可以做得更好,但通过这种方式,我可以打开abc控制台,并传递几个命令,而不是关闭此控制台。