【问题标题】:converting bash scripts to Python - how to handle heredocs?将 bash 脚本转换为 Python - 如何处理 heredocs?
【发布时间】:2013-07-25 02:00:35
【问题描述】:

我正在学习 Python,同时将一些 bash 脚本转换为 Python shell 脚本。我还不明白的一件事是如何处理这些脚本中使用的 heredocs。以下是 bash 脚本如何使用 heredocs 的两个示例:

我需要知道如何在 Python 中做的最重要的事情是第一种情况,其中 heredoc 用于提供对命令的标准响应,以便命令可以非交互方式运行:

sudo command << 'EOF'
prompt_response1
    prompt_response2
EOF

其次,tee就是这样用来创建需要sudo权限的文件的:

sudo tee /etc/xdg/autostart/updateNotificationChecker.desktop > /dev/null << 'EOF' 
[Desktop Entry]
Name=Update Notification
Exec=bash /usr/local/bin/updateNotification.sh
Terminal=false
Type=Application
NoDisplay=true
EOF

我将如何在 Python 中做这些事情?

【问题讨论】:

  • 我必须建议您学习一些 Python 方法来执行sudo command &lt;&lt;'EOF' 描述的操作,而不是像在 bash 中那样启动子进程。很可能,有一个可用的模块或库可供您针对这种情况进行探索,因此您可以在纯 python 中完成,而不是 fork() out 或上帝禁止 system()
  • 这听起来是个好建议......现在只需要知道如何去做。
  • 这只是学习语言及其提供的工具的问题;我能想象的唯一问题是提升到root权限。在程序中间跳转到root不是很好。
  • 对于像sudo 这样的事情,我认为shell 脚本是最好的。这样的事情在 Python 中很难,当你使用 system()popen2 时,你会得到一个不必要的复杂程序。在 shell 中做的事情比在 Python 中做得更好。关于 heredocs 的问题,在 Python 中可以使用多行字符串(使用textwrap.dedent() 使它们看起来更好)。
  • @AntonisChristofides 和@JoshMcGee:感谢sudo 上的信息。

标签: bash shell python


【解决方案1】:

Python 中的 Heredoc

使用多行字符串(三引号字符串'''""")。见Strings from tutorial

运行命令

import subprocess
subprocess.Popen(['cat'], stdin=subprocess.PIPE).communicate('''
    Hello multiline-string
    simliar to heredoc.
''')

【讨论】:

  • 为了清楚起见,您的“运行命令”示例可用于将响应传递给通常需要交互式输入的命令?换句话说,我正在寻找期望的替代品。问了我的问题后,我发现 Python 有 pexpect。但是您似乎在向我展示这可以通过stdin=subprocess.PIPE).communicate 来完成。真的?您的示例并不清楚,因为cat 不需要任何输入...
  • @MountainX, cat 如果没有给出命令行参数,则读取输入。
【解决方案2】:

sh(以前的 pbs)是一个成熟的 Python 子进程接口,它允许您像调用函数一样调用任何程序:

from sh import ifconfig
print(ifconfig("wlan0"))

完整文档:http://amoffat.github.com/sh
关注 Github:http://github.com/amoffat/sh

Example如何解决这个问题的第一个问题:

from sh import ssh
import os, sys

# open stdout in unbuffered mode
sys.stdout = os.fdopen(sys.stdout.fileno(), "wb", 0)

aggregated = ""
def ssh_interact(char, stdin):
    global aggregated
    sys.stdout.write(char.encode())
    aggregated += char
    if aggregated.endswith("password: "):
        stdin.put("correcthorsebatterystaple\n")

p = ssh("10.10.10.100", _out=ssh_interact, _out_bufsize=0, _tty_in=True)
p.wait()

它可以像这样处理sudo

with sudo:
    print(ls("/root"))

它有一个简洁的功能,称为 STDOUT/ERR 回调:

sh 可以使用回调来增量处理输出。这很像重定向:通过将参数传递给 _out 或 _err(或两者)特殊关键字参数,除了这一次,您传递一个可调用对象。将为您的命令输出的每一行(或块)数据调用此可调用对象。

最后,作为标准 Python 工具的一部分,raw_input 写入标准输出并从标准输入读取。这也将解决这个问题的第二个问题。

【讨论】:

    猜你喜欢
    • 2011-02-19
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 2015-10-16
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多