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

时间:2011-09-24 02:35:29

标签: python macos terminal command new-operator

我见过类似的问题(例如Running a command in a new Mac OS X Terminal window),但我需要确认这个命令及其在mac中的预期行为(我没有)。如果有人可以在Python 3 Mac中运行以下命令:

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命令吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

我没有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))

答案 1 :(得分:1)

  

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

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

  

至于实际测试:第一个测试内部双重转义\ n字符确实有效。

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

  

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

也有效。

  

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

没有理由说这也不应该起作用,事实确实如此。

  

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

由于以下几个原因,这是行不通的:

    bash中的
  • read默认读取整行,而不只是一个字符
  • 执行您提供的脚本后,终端中的shell没有理由退出
  • 即使shell退出,用户也可以配置Terminal.app在shell退出后不关闭窗口(这甚至是默认设置)

其他问题:

  • 您提供给osascript的脚本将在执行前显示在终端窗口中。在上面的例子中,用户将看到每次“这是一个测试[...]”两次。
  • 我无法弄清$EXIT应该做什么
  • ls命令只会在新终端窗口中的当前工作目录始终是用户的主目录的意义上向用户显示“当前目录”
  • 在脚本throwaway退出后,
  • bashCommand将无法使用

最后,这个脚本在Python 3下根本不起作用,因为它与TypeError崩溃:communicate()将字节字符串作为参数,而不是字符串。

  

也赞赏:在Mac上有更多的pythonic方式产生终端[...]

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