python子进程终端mac osx

时间:2013-07-22 23:48:22

标签: python macos terminal subprocess popen

长期潜伏者,第一次海报。

我知道在整个interweb中有很多关于使用子进程的例子,但我还没有找到一个解释我需要采取的步骤来生成一个新的终端窗口,并发送命令。有很多帖子提供了通过直接子进程调用启动工具和脚本的变通方法,但我还没有找到任何实际回答如何正确向终端发送命令的原始问题。

在我的情况下,我需要打开一个新的终端窗口,然后将路径发送到特定版本的应用程序,最后是我希望在该应用程序中打开的文件的路径。

我知道如何使用子进程直接调用所需的应用程序(无需打开可见终端),如何使用子进程打开新终端,以及如何调用应用程序路径或文件路径(无法使用使用--args for open()或我找到的任何其他解决方法同时执行两者。

打开它后,我无法向终端发送命令。以下是打开终端的新实例并将其发送到ls的简单版本,这不起作用。

from subprocess import Popen, PIPE, STDOUT

p = Popen(['open', '-a', 'Terminal', '-n'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

output = p.communicate(input='ls')
print(output)

这很可能是一个微不足道的问题,我只是遗漏了一些东西,但我一直无法找到信息或说明我需要的一个例子,我开始对它感到沮丧,所以我想我会问寻求帮助。

非常感谢任何帮助! TIA

2 个答案:

答案 0 :(得分:2)

  1. 首先,我怀疑你试图运行的命令是否会运行。 你先在终端试过吗? open -an Terminal会给你 一个错误。它可能应该像open -n /Applications/Utilities/Terminal.app
  2. 其次,@ korylprince是对的:open本身将创建新进程 Terminal并退出。所以你将管道与错误的过程联系起来。
  3. 第三,在将ls传递给stdin进程的那一刻 已经不存在(除非你将-W选项传递给open, 但由于这个问题肯定无济于事。)
  4. 所以我只看到一次机会:通过AppleScript。您可以创建AppleScript字符串,如下所示:

    tell application "System Events"
        tell process "Terminal"
            keystroke "ls"
            keystroke return
        end tell
    end tell
    

    然后通过Popen通过osascript -e '<your_script>'运行此脚本。

    是的,这很棘手(我说这是一个黑客)
    是的,将多行字符串传递给Popen并确定正确的终端窗口可能会出现问题 但这是有可能的。

答案 1 :(得分:2)

@cody

我对你回答的回答太长了,所以我回答是:

  1. 你是对的,如果你按照你提供的方式输入它,它会标记一个错误,如果你把-n放在终端之前,它仍会标记错误。但是,如果按照我在第一个示例中显示的方式输入它(-n在终端之后),“打开”会调用应用程序包终端的新实例,即使其中一个已经打开。
  2. 至于2-3,这就是我的研究让我相信的东西,但是我希望我错了或错过某个地方的东西,这里有人可以澄清。可悲的是,我没有弄错......

    我应该扩展我想要做的事情,因为它可能有助于通过Python生成更好的方法来实现它。

    我创建了一个工具,可以根据艺术家正在处理的电影,场景和镜头启动应用程序文件。对于某些应用程序,如Nuke和Houdini,从终端打开会为您提供丰富的信息,艺术家将无视这些信息,因此我们希望艺术家可以选择启动他们在终端中选择的文件。该终端必须是独立的,以及终端的新实例,因为我创建的应用程序必须在启动后保留,以便在不使用户定期打开应用程序的情况下在不同的应用程序中打开其他镜头。

    解析必要的信息,构建命令,以及启动启动所需应用程序的新终端都是微不足道的。对所需文件执行相同操作也很简单。选择特定版本的应用程序时会出现问题,而且我无法通过多个命令传递新生成的终端实例(老实说,我的OSX命令的语法也可能是问题,会发布再向下)。

    我可以毫无问题地使用以下两个命令:

    p = Popen(['open', '-a', 'Terminal', '-n', '--args', '/Applications/Nuke6.3v8/Nuke6.3v8.app/Nuke6.3v8'])
    
    p = Popen(['open', '-a', 'Terminal', '-n', '--args', '/Path/to/Nuke/File.nk'])  
    

    我无法让以下内容正常工作:

    p = Popen(['open', '-a', 'Terminal', '-n', '--args', '/Applications/Nuke6.3v8/Nuke6.3v8.app/Nuke6.3v8', '/Path/to/Nuke/File.nk'])
    

    从那里我的想法可能是我应该在Popen中启动终端,然后传递我需要的命令。那不行,然后我来到这里哈哈

    再次感谢您的帮助!只知道我不能发送我想要终端的命令,这为我节省了大量的时间,而这些时间本来用于持续受挫的研究。