使用 subprocess.Popen 通过 SSH 或 SCP 发送密码

新手上路,请多包涵

我正在尝试使用 subprocess.Popen 运行 scp (安全复制)命令。登录要求我发送密码:

 from subprocess import Popen, PIPE

proc = Popen(['scp', "user@10.0.1.12:/foo/bar/somefile.txt", "."], stdin = PIPE)
proc.stdin.write(b'mypassword')
proc.stdin.flush()

这会立即返回一个错误:

 user@10.0.1.12's password:
Permission denied, please try again.

确定 密码是正确的。我很容易通过在 shell 上手动调用 scp 来验证它。那么为什么这不起作用呢?

注意,有很多类似的问题,询问 subprocess.Popen 并发送自动 SSH 或 FTP 登录的密码:

如何通过 python 脚本在 linux 中设置用户密码?

使用子进程发送密码

这些问题的答案不起作用和/或不适用,因为我使用的是 Python 3。

原文由 Channel72 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.6k
2 个回答

您链接的第二个答案建议您使用 Pexpect(这通常是与期望输入的命令行程序进行交互的正确方法)。它有一个 fork 适用于你可以使用的 python3。

原文由 entropy 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是 ssh 的函数,密码使用 pexpect

 import pexpect
import tempfile

def ssh(host, cmd, user, password, timeout=30, bg_run=False):
    """SSH'es to a host using the supplied credentials and executes a command.
    Throws an exception if the command doesn't return 0.
    bgrun: run command in the background"""

    fname = tempfile.mktemp()
    fout = open(fname, 'w')

    options = '-q -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null -oPubkeyAuthentication=no'
    if bg_run:
        options += ' -f'
    ssh_cmd = 'ssh %s@%s %s "%s"' % (user, host, options, cmd)
    child = pexpect.spawn(ssh_cmd, timeout=timeout)  #spawnu for Python 3
    child.expect(['[pP]assword: '])
    child.sendline(password)
    child.logfile = fout
    child.expect(pexpect.EOF)
    child.close()
    fout.close()

    fin = open(fname, 'r')
    stdout = fin.read()
    fin.close()

    if 0 != child.exitstatus:
        raise Exception(stdout)

    return stdout

使用 scp 应该可以实现类似的东西。

原文由 sjbx 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题