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

发布于 2024-12-06 19:00:21 字数 1414 浏览 1 评论 0原文

我见过类似的问题(例如 运行命令在新的 Mac OS X 终端窗口 ),但我需要确认此命令及其在 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''')

首先,也是最基本的,“生成新终端并执行”命令是否正确? (作为参考,此版本的 runco​​m 函数来自 下面的答案,比我原来的要干净得多。)

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

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

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

谢谢!

I've seen similar questions (e.g. Running a command in a new Mac OS X Terminal window ) but I need to confirm this command and its expected behavior in a mac (which I don't have). If anyone can run the following in 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''')

Firstly, and most basically, is the "spawn new terminal and execute" command correct? (For reference, this version of the runcom function came from this answer below, and is much cleaner than my original.)

As for the actual tests: the first one tests that internal double escaped \\n characters really work. The second tests that we can put (unescaped) newlines into the "script" and still have it work just like semicolon. Finally, the last one tests whether you can call a sudo process in a separate terminal (my ultimate goal).

In all cases, the new terminal should disappear as soon as you "press any key". Please also confirm this.

If one of these doesn't work, a correction/diagnosis would be most appreciated. Also appreciated: is there a more pythonic way of spawning a terminal on Mac then executing a (sudo, extended) bash commands on it?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月依秋水 2024-12-13 19:00:21

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

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

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

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

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

这也有效。

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

没有理由说这也不行,而且确实行得通。

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

由于以下几个原因,这将不起作用:

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

其他问题:

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

最后,该脚本在 Python 3 下根本无法工作,因为它会崩溃并出现以下错误: 类型错误communicate() 采用字节字符串作为参数,而不是字符串。

还赞赏:是否有一种更Pythonic的方式在Mac上生成终端[...]

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

[...] its expected behavior [...]

This is hard to answer, since those commands do what I expect them to do, which might not be what you expect them to do.

As for the actual tests: the first one tests that internal double escaped \n characters really work.

The \\n with the doubled backslash does indeed work correctly in that it causes echo to emit a newline character. However, no double quotes are emitted by echo.

The second tests that we can put (unescaped) newlines into the "script" and still have it work just like semicolon.

That works also.

Finally, the last one tests whether you can call a sudo process in a separate terminal (my ultimate goal).

There is no reason why this should not work also, and indeed it does.

In all cases, the new terminal should disappear as soon as you "press any key". Please also confirm this.

That will not work because of several reasons:

  • read in bash will by default read a whole line, not just one character
  • after the script you supply is executed, there is no reason for the shell within the terminal to exit
  • even if the shell would exit, the user can configure Terminal.app not to close a window after the shell exits (this is even the default setting)

Other problems:

  • the script you supply to osascript will appear in the terminal window before it is executed. in the examples above, the user will see every "This is a test [...]" twice.
  • I cannot figure out what $EXIT is supposed to do
  • The ls command will show the user "the current directory" only in the sense that the current working directory in a new terminal window will always be the user's home directory
  • throwaway will not be available after the script bashCommand exits

Finally, this script will not work at all under Python 3, because it crashes with a TypeError: communicate() takes a byte string as argument, not a string.

Also appreciated: is there a more pythonic way of spawning a terminal on Mac [...]

You should look into PyObjC! It's not necessarily more pythonic, but at least you would eliminate some layers of indirection.

冷清清 2024-12-13 19:00:21

我没有 Python 3,但我稍微编辑了您的 runco​​m 函数,它应该可以工作:

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))

I don't have Python 3, but I edited your runcom function a little and it should work:

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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文