2013-07-22 118 views
2

长期潜伏者,第一次海报。蟒蛇子进程终端mac osx

我知道整个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

+1

这很不容易,就像你想的那样。终端打开它自己的子进程(例如bash)并直接与它们进行通信。向终端的stdin发送任何内容都不会进入其他进程。您可能错误地处理了这个问题。 – korylprince

+0

谢谢korylprince,我会试着去改变它。欣赏回应。 – Glenn

回答

1
  1. 首先,我怀疑你试图运行的命令是否会运行。 您是否先在终端试用过? open -an Terminal会给你 一个错误。它可能应该是这样的open -n /Applications/Utilities/Terminal.app
  2. 其次,@ korylprince是正确的:open本身将创建Terminal的新进程 并退出。所以你正在将管道连接到错误的进程。
  3. 第三,通过ls这一进程 标准输入不存在(除非你将通过-W选项的open, 但肯定不会因为2个问题帮)的时刻。

所以我看到只有一个机会来做到这一点:通过AppleScript。你可以像下一个创造一个AppleScript字符串,东西:

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

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

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

1

@cody

我对你的回答的响应时间过长,因此我想提出一个答案回应:

  1. 你是正确的,如果你进入它,你所提供的方式,它的标志错误,并且如果您在终端之前放置了-n,它仍会标记错误。但是,如果按照我在第一个示例中显示的方式(在终端之后的-n)输入,“打开”将调用应用程序包终端的新实例,即使其中一个已经打开。

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

再次感谢您的帮助!只要知道我无法发送到我想要的终端命令,就可以为我节省大量的时间,而这些时间本来会花在持续不断的研究上。