<p>好的,现在可以了。我找到了这些有用的帖子:</p>
<p><a href="https://github.com/ansible/ansible/pull/4100" rel="nofollow">Add paramiko ssh agent forwarding (optional) #4100</a><br/>
<a href="https://github.com/paramiko/paramiko/issues/89" rel="nofollow">open_forward_agent_channel vs. open_session #89</a></p>
<p>最终代码是:</p>
<pre><code>#!/usr/bin/python3
# -*- coding: utf-8 -*-
import paramiko
class SSHSession:
def __init__(self, server_address, user='root', port=22):
self.connected = False
self.server_address = server_address
self.user = user
self.port = port
def connect(self):
try:
self.ssh_client = paramiko.SSHClient()
self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh_client.connect(self.server_address, username=self.user)
self.transport = self.ssh_client.get_transport()
self.agent_channel = self.transport.open_session()
self.agent_handler = paramiko.agent.AgentRequestHandler(self.agent_channel)
self.channel = self.ssh_client.invoke_shell()
except:
self.connected = False
else:
self.connected = True
return self.connected
def exec_command(self, command, newline='\r'):
if not self.connected:
raise Exception('Not connected')
else:
timeout = 31536000 # 365 days in seconds
self.channel.settimeout(timeout)
line_buffer = ''
channel_buffer = ''
end_string = 'CLIENT_EXPECT_CMD_OK'
print('[SEND ] >>', command)
self.channel.send(command + ' ; echo ' + end_string + newline)
while True:
channel_buffer = self.channel.recv(1).decode('UTF-8')
if len(channel_buffer) == 0:
raise Exception('connection lost with server: ' + self.server_address)
break
channel_buffer = channel_buffer.replace('\r', '')
if channel_buffer != '\n':
line_buffer += channel_buffer
else:
if line_buffer == end_string:
break
print('[RECEIVE] <<', line_buffer)
line_buffer = ''
def disconnect(self):
self.ssh_client.close()
def __enter__(self):
self.connect()
return self
def __exit__(self, _type, value, traceback):
self.disconnect()
if __name__ == "__main__":
server_address = 'firstserver'
ssh_user = 'root'
with SSHSession(server_address) as ssh_session:
ssh_session.exec_command('hostname')
ssh_session.exec_command('ssh root@secondserver hostname')
</code></pre>
<p>输出为:</p>
^{pr2}$
<p>启用代理转发的代码的重要部分是:</p>
<pre><code>self.agent_channel = self.transport.open_session()
self.agent_handler = paramiko.agent.AgentRequestHandler(self.agent_channel)
</code></pre>