对于每个ssh命令要求输入密码,Python

时间:2013-07-23 14:05:53

标签: python python-2.7 python-3.x ssh subprocess

我正在尝试执行以下代码,虽然我在代码中提供了密码,但它会询问每个ssh命令的密码。任何人都可以告诉我我在哪里做错了。提前致谢

import signal
from subprocess import call, PIPE, Popen
from time import sleep
import os, pty
class SshCmd:

    socket = ''
    pid = 0
    password = None

    def __init__(self, password = None):
        if password:
            SshCmd.password = password

            # start agent
            devnull = open(os.devnull, 'w')
            call(['killall', 'ssh-agent'], stderr=devnull)
            process = Popen('/usr/bin/ssh-agent', stdout=PIPE, stderr=devnull)
            stdout, stderr = process.communicate()
            lines = stdout.splitlines()
            SshCmd.socket = lines[0].decode().split(';')[0].split('=')[1]
            SshCmd.pid = lines[1].decode().split(';')[0].split('=')[1]
            devnull.close()

            # unlock key
            pid, fd = pty.fork()
            if 0 == pid:
                # child adds key
                os.execve('/usr/bin/ssh-add', ['/usr/bin/ssh-add'], \
                    {'SSH_AUTH_SOCK': SshCmd.socket, 'SSH_AGENT_PID': SshCmd.pid})
            else:
                # parent send credentials
                cmsg = os.read(fd, 1024)
                os.write(fd, SshCmd.password.encode())
                os.write(fd, os.linesep.encode())
                cmsg = os.read(fd, 1024)
                if len(cmsg) <= 2:
                    os.waitpid(pid, 0)
                else:
                    os.kill(pid, signal.SIGTERM)

    def execve(self, path, args, env = {}):
        if not SshCmd.password:
            return
        pid = os.fork()
        if 0 == pid:
            env['SSH_AUTH_SOCK'] = SshCmd.socket
            env['SSH_AGENT_PID'] = SshCmd.pid
            os.execve(path, args, env)
        else:
            os.waitpid(pid, 0)

    def ssh(self, user, host, cmd, args = []):
        cmdLine = cmd
        for arg in args:
            cmdLine += ' '
            cmdLine += arg
        self.execve('/usr/bin/ssh',
                ['/usr/bin/ssh',
                '-o',
                'UserKnownHostsFile=/dev/null',
                '-o',
                'StrictHostKeyChecking=false',
                '%(user)s@%(host)s' % {'user': user, 'host': host},
                cmdLine])

if '__main__' == __name__:
    other = SshCmd('passowrd')
    other.ssh('root', 'host', '/sbin/ifconfig')
    other.ssh('root', 'host', 'ping', ['-c', '5', 'localhost'])

1 个答案:

答案 0 :(得分:0)

你没犯错误。要跳过密码步骤,您需要预先验证您的请求,您可以先使用命令ssh-copy-id来执行此操作。它将存储凭据并允许通过密钥进行连接。您需要先拥有一个密钥,您可以使用ssh-keygen

创建密钥

注意:这些命令可能会根据Linux发行版而改变。