我正在将我写的一个Bash脚本改写成Python。那个脚本的关键是
ssh -t first.com "ssh second.com very_remote_command"
我正在使用paramiko进行嵌套认证时遇到问题。我没有找到任何处理我的精确情况的示例,但是我找到了在远程主机上使用sudo的示例。 第一种方法写入stdin。
ssh.connect('127.0.0.1', username='jesse', password='lol')
stdin, stdout, stderr = ssh.exec_command("sudo dmesg")
stdin.write('lol\n')
stdin.flush()
第二个示例创建一个频道并使用类似套接字的发送和接收。
我能够在sudo上使用stdin.write,但在远程主机上的ssh无法正常工作。
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('first.com', username='luser', password='secret')
stdin, stdout, stderr = ssh.exec_command('ssh luser@second.com')
stdin.write('secret')
stdin.flush()
print '---- out ----'
print stdout.readlines()
print '---- error ----'
print stderr.readlines()
ssh.close()
...打印...
---- out ----
[]
---- error ----
['Pseudo-terminal will not be allocated because stdin is not a terminal.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied, please try again.\r\n', 'Permission denied (publickey,password,keyboard-interactive).\r\n']
伪终端错误让我想起了原始命令中的-t标志,因此我切换到第二种方法,使用通道。而不是ssh.exec_command和后来的操作,我现在使用:
t = ssh.get_transport()
chan = t.open_session()
chan.get_pty()
print '---- send ssh cmd ----'
print chan.send('ssh luser@second.com')
print '---- recv ----'
print chan.recv(9999)
chan = t.open_session()
print '---- send password ----'
print chan.send('secret')
print '---- recv ----'
print chan.recv(9999)
...... 但它会打印'---- send ssh cmd ----',并一直等待直到我杀死进程。
我对Python和网络一窍不通。在第一种情况下,为什么使用sudo发送密码可以工作,而使用ssh无法工作?提示是否不同?Paramiko是否是正确的库?
while
循环挂起,请在调用 shell 命令后设置chan.settimeout(3)
并处理socket.timeout
异常。 - simnochan
是一种套接字类型,因此recv
只需要获取任意数量的数据。在文档中,我发现应该使用2的幂次方。另外,有一个无意义的赋值。现在我会这样做:buff += chan.recv(4096)
。https://docs.python.org/3/library/socket.html#socket.socket.recv - mqsoh