3

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

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

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

我知道如何使用子进程直接调用所需的应用程序(不打开可见终端),如何使用子进程打开新终端,以及如何调用应用程序路径或文件路径(无法同时获得使用 --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

4

2 回答 2

2
  1. 首先,我怀疑您尝试运行的命令是否会运行。您是否先在终端中尝试过?open -an Terminal会给你一个错误。它可能应该是这样的open -n /Applications/Utilities/Terminal.app
  2. 其次,@korylprince 是对的:open它自己会创建新的进程Terminal并退出。因此,您将管道与错误的进程联系起来。
  3. 第三,在传递ls给 stdin 的那一刻,该进程并不存在(除非您将 -W 选项传递给open,但由于 2 问题,它肯定无济于事)。

所以我认为只有一个机会可以做到这一点:通过 AppleScript。您可以创建一个 AppleScript 字符串,如下所示:

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

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

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

于 2013-07-23T06:08:57.683 回答
2

@科迪

我对您的回答的回复太长了,因此我正在回答:

  1. 你是对的,如果你按照你提供的方式输入它,它会标记一个错误,如果你把 -n 放在终端之前,它仍然会标记一个错误。但是,如果您按照我在第一个示例中显示的方式输入它(终端后的-n)“打开”会调用应用程序捆绑终端的新实例,即使一个已经打开。

至于 2-3,这是我的研究让我相信的,但我希望我错了或在某个地方遗漏了一些东西,这里有人可以澄清一下。可惜我没看错……

我可能应该扩展我正在尝试做的事情,因为它可能有助于生成更好的方法来通过 Python 完成它。

我创建了一个工具,可以根据艺术家正在制作的电影、场景和镜头启动应用程序文件。对于某些应用程序,例如 Nuke 和 Houdini,从终端打开会为您提供艺术家将无法看到的大量信息,因此我们希望为艺术家提供在终端中启动他们选择的文件的选项。该终端必须是独立的,并且是终端的新实例,因为我创建的应用程序必须在启动后持续存在,以便在不同的应用程序中打开其他镜头,而无需让用户经常打开应用程序。

解析必要的信息、构建命令并启动一个新的终端来启动所需的应用程序都是微不足道的。对所需文件执行相同操作也很简单。The issue arises when a particular version of the app is chosen, and I have not been able to pass the newly birthed instance of Terminal with more than a single command (honestly the syntax of my OSX command may be the issue as well, will post再向下)。

我可以让以下两个命令正常工作:

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 中启动终端,然后传递我需要的命令。那没有用,然后我来到这里大声笑

再次感谢任何帮助!仅仅知道我无法发送到我想要终端的命令,就可以节省大量时间,这些时间本来可以花在持续受挫的研究上。

于 2013-07-23T18:01:02.547 回答