我知道已经发布了类似的问题,但是我所见过的任何方法似乎都不起作用。我想在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所说,
open命令将打开一个文件(或目录或URL),就像您双击该文件的图标一样。
最终,该应用程序由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
相同的操作。)为了将来的读者受益,我将在评论中包括以下信息:
如果仅向
stdin
写一行,然后从函数返回/从主脚本等的结尾退出,则Popen
对象将被垃圾回收,同时关闭其两个管道。如果xfoil
尚未完成运行,则下次尝试写入任何输出时会出现错误,并且显然可以通过打印Fortran runtime error: end of file
(到stderr?)并进行打包来处理此错误。您需要调用xfoil.wait()
(或其他隐式wait
s)以防止这种情况发生。关于python - 如何通过python子进程与Mac上的应用程序进行交互?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15010650/