Python - 将控制台命令传递给第 3 方控制台应用程序
Python - pass console command to 3rd party console application
我有一个问题,但很难为我解释:
我有一个应用程序(我们称之为 abc),它有自己的控制台 - 这个 soncole 运行s 通过 CMD 像这样:
abc console console.xml
abc 控制台以相同的 window 开始,但是 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()
没有任何反应,控制台冻结。我尝试添加更多命令,以检查尽管 "freeze" 我是否可以做一些事情,比如导出一些 xml,但没有任何反应。
有什么方法可以将任何命令传递给 abc 吗?
如果您的应用程序足够简单,它可能会通过其标准输入接受命令。如果您直接在 shell 中 运行 它,它会直接从您自己提供的输入中获取标准输入(除非您使用重定向)。
但是如果你 运行 它作为另一个 Python 程序的子进程并且你想自动化它的输入,你必须告诉你的 Python 代码将该输入提供给应用程序的标准输入通道。
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()
不是 return 管道,而是包含所有输出的字符串。因此,您需要确保您的应用程序自行结束(或通过向其发送使其退出的命令),否则 check_output()
将永远等待。如果你不能或不想让它立即退出,你需要使用更灵活的Popen()
接口并根据需要写入/读取。
感谢 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()
也许它并不完美,更高级的用户可以做得更好,但通过这种方式我可以打开 abc 控制台,并向那里传递一些命令,而不是关闭这个控制台。
我有一个问题,但很难为我解释:
我有一个应用程序(我们称之为 abc),它有自己的控制台 - 这个 soncole 运行s 通过 CMD 像这样:
abc console console.xml
abc 控制台以相同的 window 开始,但是 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()
没有任何反应,控制台冻结。我尝试添加更多命令,以检查尽管 "freeze" 我是否可以做一些事情,比如导出一些 xml,但没有任何反应。
有什么方法可以将任何命令传递给 abc 吗?
如果您的应用程序足够简单,它可能会通过其标准输入接受命令。如果您直接在 shell 中 运行 它,它会直接从您自己提供的输入中获取标准输入(除非您使用重定向)。
但是如果你 运行 它作为另一个 Python 程序的子进程并且你想自动化它的输入,你必须告诉你的 Python 代码将该输入提供给应用程序的标准输入通道。
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()
不是 return 管道,而是包含所有输出的字符串。因此,您需要确保您的应用程序自行结束(或通过向其发送使其退出的命令),否则 check_output()
将永远等待。如果你不能或不想让它立即退出,你需要使用更灵活的Popen()
接口并根据需要写入/读取。
感谢 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()
也许它并不完美,更高级的用户可以做得更好,但通过这种方式我可以打开 abc 控制台,并向那里传递一些命令,而不是关闭这个控制台。