如何通过python子进程与mac上的应用程序进行交互?

时间:2013-02-21 19:29:37

标签: python macos subprocess

我知道已经发布了类似的问题,但我所看到的方法似乎没有用。我想在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发送命令。

1 个答案:

答案 0 :(得分:3)

正如man page所说,

  

打开命令会打开一个文件(或目录或网址),就像您双击文件的图标一样。

最终,应用程序由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?)和bailing来处理此问题。您需要致电xfoil.wait()(或隐含wait s的其他内容)以防止这种情况发生。