【问题标题】:SSH into a server, run a command and save its output to a variable in PythonSSH 进入服务器,运行命令并将其输出保存到 Python 中的变量
【发布时间】:2014-12-31 05:48:22
【问题描述】:

我正在将一个 bash 程序翻译成 Python,并且已经完成了所有工作。这是 bash 代码,它只是通过 SSH 连接到服务器,执行 PostgreSQL 数据库转储,如果没有错误,则将其保存到文件中。

output="$(ssh "$SSH_LOCATION" bash <<< "$(printf 'PGPASSWORD=%q pg_dump -U %q %q' "$pg_pass" "$pg_user" "$database")")"

if [[ $? -ne 0 ]]
then
    echo "$output"
    echo "An error occurred while dumping the database"
    exit $?
else
    echo "$output" > ~/"$LOCAL_DIR"/"$database"
fi

变量SSH_LOCATIONLOCAL_DIRpg_passpg_userdatabase都是在Python程序中定义的。

对远程 shell 的变量进行转义,尤其是 pg_pass,非常重要。这是由printf '%q' 在 bash 代码中处理的。

将上述 bash 代码转换为 Python 的最佳方法是什么?

编辑:还有一个警告,身份验证是由公钥处理的,而不是密码。当然,ssh shell 命令会自动处理这个问题。

【问题讨论】:

  • 我想说“把子进程扔到这里”。但如果被问到“到底是怎么做到的”,我真的会不知所措
  • @inspectorG4dget 我可以做subproccess.Popen(['bash', '-c', """BASH CODE"""]),并从 python 提供所有变量。不过感觉有点太老套了。
  • 也可以考虑pexpect

标签: python bash ssh


【解决方案1】:

如果您想使用paramiko ssh 进入盒子,您的 python 代码将类似于以下内容。

import paramiko
import copy

def ssh_server(server, username=username, password=password, pg_pass, ps_user, database):
    client = paramiko.SSHClient()
    client.load_system_host_keys()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(server, username, password)
    stdin, stdout, stderr = client.exec_command("PGPASSWORD=%s pg_dump -U %s %s" % (pg_pass, $pg_user, $database))
    output = copy.deepcopy(stdout.readlines())
    error = copy.deepcopy(stderr.readlines())
    client.close()
    if not error and output:
        return stdout.readlines()
    else:
        print "An error occured\n%s" % error
        return False

以下代码只是一个示例。当然,它需要根据您的需要进行调整。 Paramiko 支持 RSA 密钥和密码。如果可以ssh无密码,则不需要提供密码,然后将密码参数取出。

【讨论】:

    【解决方案2】:

    将上述 bash 代码转换为 Python 的最佳方法是什么?

    此类问题的答案通常是:使用plumbum

    借用docs,这应该足以轻松演示如何使用它(以及它有多棒),您可以执行以下操作:

    rem = SshMachine("hostname", user = "john", keyfile = "/path/to/idrsa")
    output = rem.which("ls")
    

    【讨论】:

    • 谢谢,这是最简单的答案。我所要做的就是你的第一行代码,然后print(rem["ls"]()) 远程获取ls 的输出。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 2017-09-21
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-07
    • 2010-12-24
    相关资源
    最近更新 更多