【问题标题】:OS X & Python 3: Behavior while executing bash command in new terminal?OS X 和 Python 3:在新终端中执行 bash 命令时的行为?
【发布时间】:2011-11-24 02:19:45
【问题描述】:

我见过类似的问题(例如 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 进程(我的最终目标)。

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

如果其中一项不起作用,我们将非常感谢您进行更正/诊断。也赞赏:是否有一种更 Python 的方式在 Mac 上生成终端然后在其上执行(sudo,扩展)bash 命令?

谢谢!

【问题讨论】:

  • $EXIT 应该做什么?

标签: python macos terminal command new-operator


【解决方案1】:

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

这很难回答,因为这些命令执行期望它们执行的操作,而这可能不是期望它们执行的操作。

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

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

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

这也有效。

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

没有理由不这样做也不行,而且确实如此。

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

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

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

其他问题:

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

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

也赞赏:有没有更 Pythonic 的方式在 Mac 上生成终端 [...]

您应该研究 PyObjC!它不一定更pythonic,但至少你会消除一些间接层。

【讨论】:

  • 很有启发性,谢谢!用TypeError 很好地抓住了!追问: 1.有没有办法让命令在执行之前不显示在弹出终端中? 2. $EXIT 应该在完成 bashCommand 后强制新生成的终端退出。你说终端没有关闭,但是:(有没有办法让它这样做?非常感谢你的详细程度。
  • @scarlet:我仍然没有得到 $EXIT ......你不能随便把一些虚构的词贴在某个地方并期望它做任何事情。你从哪里得到那个的?也许这是您找到的解决方案的一半?
  • 大概就是这样,是的。作为更新,我发现在 osascript 中“以管理员权限”运行某些东西会弹出一个图形登录,从而消除了对终端的需要。这是你没有意识到的那些愚蠢的事情之一,除非你真的有一个 mac :( 更新的代码现在是 process.communicate( '''do shell script "{0}" with administrator privileges'''.format(bashCommand).encode() ),或多或少。
【解决方案2】:

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

【讨论】:

  • 这看起来干净多了。我将把它编辑到原始数据请求中!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2013-10-18
  • 2018-10-24
  • 2018-08-15
  • 2011-11-02
  • 2011-04-13
相关资源
最近更新 更多