我知道已经发布了类似的问题,但我所看到的方法似乎没有用。我想在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发送命令。
答案 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的其他内容)以防止这种情况发生。