我想连接到SFTP服务器并执行命令,例如ls
。但是我遇到一个错误:
paramiko.ssh_exception.SSHException:无法打开频道。
import paramiko
import pysftp
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('xxxxxxxx', username='xxxxxxx', password='xxxxxxxx', key_filename='xxxxxxxxxxx')
stdin, stdout, stderr = ssh.exec_command('ls')
print stdout.readlines()
ssh.close()
exit()
答案 0 :(得分:0)
您似乎认为您的代码执行了SFTP ls
命令。它不是。它尝试执行ls
shell 命令。您的服务器甚至可能不允许执行shell命令,因此会出现错误。
如果要使用SFTP,则需要使用SFTPClient
class及其方法,例如SFTPClient.listdir
。
请注意,SFTP协议没有像ls
这样的文本命令。 SFTP是二进制协议。您所知道的命令是通用SFTP客户端的命令-OpenSSH sftp
。它将用户文本命令映射到二进制SFTP协议请求。 Paramiko SFTPClient
类将对其方法的调用映射到等效的二进制SFTP协议请求的方式。
有关更多详细信息,请参见我对SSH invocation of a subsystem SFTP using command line的回答。
答案 1 :(得分:0)
我的问题的答案如下:
pkey = paramiko.RSAKey.from_private_key_file('/Users/rajesh.maulekhi/Downloads/id_rsa')
def multifactor_auth_sftp_client(host, port, username, key, password):
#Create an SSH transport configured to the host
transport = paramiko.Transport((host, port))
#Negotiate an SSH2 session
transport.connect()
#Attempt authenticating using a private key
transport.auth_publickey(username, key)
#Create an event for password auth
password_auth_event = threading.Event()
#Create password auth handler from transport
password_auth_handler = paramiko.auth_handler.AuthHandler(transport)
#Set transport auth_handler to password handler
transport.auth_handler = password_auth_handler
#Aquire lock on transport
transport.lock.acquire()
#Register the password auth event with handler
password_auth_handler.auth_event = password_auth_event
#Set the auth handler method to 'password'
password_auth_handler.auth_method = 'password'
#Set auth handler username
password_auth_handler.username = username
#Set auth handler password
password_auth_handler.password = password
#Create an SSH user auth message
userauth_message = paramiko.message.Message()
userauth_message.add_string('ssh-userauth')
userauth_message.rewind()
#Make the password auth attempt
password_auth_handler._parse_service_accept(userauth_message)
#Release lock on transport
transport.lock.release()
#Wait for password auth response
password_auth_handler.wait_for_response(password_auth_event)
#Create an open SFTP client channel
return transport.open_sftp_client()