OS X&Python 3:在新终端中执行bash命令时的行为?

问题描述:

我见过类似的问题(例如Running a command in a new Mac OS X Terminal window),但我需要确认此命令及其在Mac中的预期行为(我没有)。如果任何人都可以运行在Python 3的Mac如下:OS X&Python 3:在新终端中执行bash命令时的行为?

import subprocess, os 
def runcom(bashCommand): 
    sp = subprocess.Popen(['osascript'], stdin=subprocess.PIPE, stderr=subprocess.PIPE) 
    sp.communicate('''tell application "Terminal"\nactivate\ndo script with command "{0} $EXIT"\nend tell'''.format(bashCommand)) 

runcom('''echo \\"This is a test\\n\\nThis should come two lines later; press any key\\";read throwaway''') 
runcom('''echo \\"This is a test\\"\n\necho \\"This should come one line later; press any key\\";read throwaway''') 
runcom('''echo \\"This is testing whether I can have you enter your sudo pw on separate terminal\\";sudo ls;\necho \\"You should see your current directory; press any key\\";read throwaway''') 

首先,也是最根本,是“产生新的终端,并执行”命令是否正确? (仅供参考,这个版本的runcom功能从this answer below来了,比我原来干净多了。)

至于实际的测试:第一个测试,内部双转义字符\\n真正的工作。第二个测试我们可以将(非转义的)换行符放入“脚本”中,并且仍然像分号一样工作。最后,最后一个测试是否可以在单独的终端中调用sudo进程(我的最终目标)。

在任何情况下,只要您按下任意键,新终端就会消失。也请确认这一点。

如果其中一个不起作用,更正/诊断将不胜感激。也赞赏:是否有更多pythonic方式在Mac上产生终端,然后在其上执行(sudo,extended)bash命令?

谢谢!

+0

$ EXIT应该做什么? – hop

[...]其预期的行为[...]

这很难回答,因为这些命令会做他们期望它们做的事情,这可能不是希望他们做的事情。

至于实际测试:第一个测试,内部双转义字符真正工作。

\\n与一倍反斜杠确实的,因为它会导致echo发出一个换行符正常工作。但是,echo不会发出双引号。

第二个测试,我们可以把(非转义的)换行符放入“脚本”,并仍然像分号一样工作。

这也适用。

最后,最后一个测试是否可以在单独的终端(我的最终目标)中调用sudo进程。

有没有理由为什么这不应该也工作,并且确实如此。

在所有情况下,只要您按下任意键,新终端就会消失。也请确认这一点。

这不会因为几个原因有:执行您提供的脚本后

  • read在bash会默认读取一整行,而不仅仅是一个字符
  • ,没有原因是终端内的外壳退出
  • 即使外壳退出,用户也可以配置Terminal.app在外壳退出后不关闭窗口(这甚至是默认设置)

其他问题:

  • 你提供给osascript脚本会在执行之前出现在终端窗口。在上面的例子中,用户会看到每个“这是一个测试”两次。
  • 我想不出什么$EXIT是应该做的
  • ls命令仅在这个意义上显示用户“当前目录”,在新的终端窗口中的当前工作目录将永远是用户的主目录
  • throwaway将无法​​使用该脚本bashCommand退出

后最后,该脚本将不Python的3下在所有的工作,因为它以TypeError崩溃:communicate()需要一个字节的字符串作为参数,而不是字符串。

还赞赏:有产卵在Mac终端的更Python的方式[...]

你应该看看PyObjC!它不一定是更pythonic,但至少你会消除一些间接的层。

+0

非常有启发性,谢谢!和'TypeError'很好的结合! 跟进: 1.是否有办法让命令在执行前不显示在弹出式终端中? 2. $ EXIT应该强制新生成的终端在完成bashCommand后退出。你说终端不关闭,但是:(有没有办法让它这样做? 非常感谢你的详细程度 – scarlet

+0

@scarlet:我还是没有得到$ EXIT ...你可以' t只是villy-nilly在某处粘贴了一些发明的词,并期望它做任何事情,你从哪里得到的?也许这是你找到的解决方案的一半? – hop

+0

可能是这样,是的,作为一个更新,我发现运行的东西在osascript“拥有管理员权限”弹出一个图形登录,从而避免了终端的需要,这是你不知道的一些愚蠢的事情,除非你真的有一个mac :(更新后的代码现在是'process.communicate(' ''使用管理员权限'''。格式(bashCommand).encode())'执行shell脚本{0},或多或少。 – scarlet

我没有Python 3中,但我编辑您的runcom功能一点,它应该工作:

def runcom(bashCommand): 
    sp = subprocess.Popen(['osascript'], stdin=subprocess.PIPE, stderr=subprocess.PIPE) 
    sp.communicate('''tell application "Terminal"\nactivate\ndo script with command "{0} $EXIT"\nend tell'''.format(bashCommand)) 
+0

这看起来很干净。我将把它编辑为原始数据请求!谢谢! – scarlet