我知道已经发布了类似的问题,但我见过的方法似乎都不起作用。我想在 mac 上使用 python 子进程启动应用程序 xfoil,并使用脚本向 xfoil 发送一堆命令(xfoil 是一个在终端窗口中运行的应用程序,您可以通过文本命令与其交互)。我可以使用脚本启动 xfoil,但我似乎不知道如何向它发送命令。这是我当前正在尝试的代码:
import subprocess as sp
xfoil = sp.Popen(['open', '-a', '/Applications/Xfoil.app/Contents/MacOS/Xfoil'], stdin=sp.PIPE, stdout=sp.PIPE)
stdout_data = xfoil.communicate(input='NACA 0012')
我也尝试过
xfoil.stdin.write('NACA 0012\n')
为了向 xfoil 发送命令。
最佳答案
作为man page说,
The open command opens a file (or a directory or URL), just as if you had double-clicked the file's icon.
最终,应用程序由 LaunchServices 启动,但这并不重要 - 重要的是它不是您的 shell 或 Python 脚本的子级。
此外,open
的全部意义在于打开应用程序本身,因此您不必深入研究它并找到 Unix 可执行文件。如果您已经有了它,并且想将其作为 Unix 可执行文件运行……只需运行它即可:
xfoil = sp.Popen(['/Applications/Xfoil.app/Contents/MacOS/Xfoil'], stdin=sp.PIPE, stdout=sp.PIPE)
事实证明,在这种情况下,MacOS/Xfoil
甚至不是正确的程序;它显然是 Resources/xfoil
的某种包装,这实际上相当于 Linux 上的 /usr/local/bin/xfoil
。所以你想这样做:
xfoil = sp.Popen(['/Applications/Xfoil.app/Contents/Resouces/xfoil'], stdin=sp.PIPE, stdout=sp.PIPE)
(此外,从技术上讲,您的命令行根本不应该工作;-a
指定一个应用程序,而不是 Unix 可执行文件,并且您应该将至少一个文件传递给但由于 LaunchServices 可以像应用程序一样启动 Unix 可执行文件,并且 open
不会检查参数是否有效,因此 open -a/Applications/Xfoil.app/Contents/MacOS/Xfoil
最终有效地执行与 open/Applications/Xfoil.app/Contents/MacOS/Xfoil
相同的操作。)
为了 future 读者的利益,我将在评论中添加以下信息:
如果您只是向 stdin
写入一行,然后从函数返回/脱离主脚本末尾等,则 Popen
对象将变得垃圾收集,关闭其两个管道。如果 xfoil 尚未完成运行,下次尝试写入任何输出时它将收到错误,显然它通过打印 Fortran 运行时错误:文件结束来处理此问题code> (到 stderr?) 和 bailing。您需要调用xfoil.wait()
(或其他隐式等待
的东西)以防止这种情况发生。
关于python - 如何通过 python 子进程与 mac 上的应用程序交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15010650/