我正在尝试执行以下代码,虽然我在代码中提供了密码,但它会询问每个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'])
答案 0 :(得分:0)
你没犯错误。要跳过密码步骤,您需要预先验证您的请求,您可以先使用命令ssh-copy-id
来执行此操作。它将存储凭据并允许通过密钥进行连接。您需要先拥有一个密钥,您可以使用ssh-keygen
注意:这些命令可能会根据Linux发行版而改变。