Python中的SFTP? (平台独立)

我正在研究一个简单的工具,将文件传输到硬编码的位置,密码也是硬编码的。 我是一个python新手,但是感谢ftplib,这很简单:

import ftplib info= ('someuser', 'password') #hard-coded def putfile(file, site, dir, user=(), verbose=True): """ upload a file by ftp to a site/directory login hard-coded, binary transfer """ if verbose: print 'Uploading', file local = open(file, 'rb') remote = ftplib.FTP(site) remote.login(*user) remote.cwd(dir) remote.storbinary('STOR ' + file, local, 1024) remote.quit() local.close() if verbose: print 'Upload done.' if __name__ == '__main__': site = 'somewhere.com' #hard-coded dir = './uploads/' #hard-coded import sys, getpass putfile(sys.argv[1], site, dir, user=info) 

问题是我找不到任何支持sFTP的库。 什么是安全地做这样的事情的正常方法?

编辑:感谢这里的答案,我已经得到它与Paramiko工作,这是语法。

 import paramiko host = "THEHOST.com" #hard-coded port = 22 transport = paramiko.Transport((host, port)) password = "THEPASSWORD" #hard-coded username = "THEUSERNAME" #hard-coded transport.connect(username = username, password = password) sftp = paramiko.SFTPClient.from_transport(transport) import sys path = './THETARGETDIRECTORY/' + sys.argv[1] #hard-coded localpath = sys.argv[1] sftp.put(localpath, path) sftp.close() transport.close() print 'Upload done.' 

再次感谢!

Paramiko支持SFTP。 我用过了,而且我用过Twisted。 两者都有自己的位置,但是你可能会发现从Paramiko开始更容易。

你应该检查pysftp https://pypi.python.org/pypi/pysftp它取决于paramiko,但最常见的用例只是几行代码。;

 import pysftp import sys path = './THETARGETDIRECTORY/' + sys.argv[1] #hard-coded localpath = sys.argv[1] host = "THEHOST.com" #hard-coded password = "THEPASSWORD" #hard-coded username = "THEUSERNAME" #hard-coded with pysftp.Connection(host, username=username, password=password) as sftp: sftp.put(localpath, path) print 'Upload done.' 

如果你想轻松简单,你可能也想看织物 。 这是一个像Ruby的Capistrano这样的自动部署工具,但是对于Python来说更简单和便利。 它build立在Paramiko之上。

你可能不想做'自动化部署',但是Fabric可以完美地适应你的用例。 为了向您展示Fabric是多么简单:您的脚本的fab文件和命令看起来像这样(未testing,但99%肯定会起作用):

fab_putfile.py:

 from fabric.api import * env.hosts = ['THEHOST.com'] env.user = 'THEUSER' env.password = 'THEPASSWORD' def put_file(file): put(file, './THETARGETDIRECTORY/') # it's copied into the target directory 

然后用fab命令运行该文件:

 fab -f fab_putfile.py put_file:file=./path/to/my/file 

你完成了! 🙂

我会坚持一个纯粹的Python解决scheme,但不是没有Windows ssh选项。 Cygwin有一个例子,还有更多 。

这是一个使用pysftp和一个私钥的示例。

 import pysftp def upload_file(file_path): private_key = "~/.ssh/your-key.pem" # can use password keyword in Connection instead srv = pysftp.Connection(host="your-host", username="user-name", private_key=private_key) srv.chdir('/var/web/public_files/media/uploads') # change directory on remote server srv.put(file_path) # To download a file, replace put with get srv.close() # Close connection 

pysftp是一个易于使用的sftp模块,利用paramiko和pycrypto。 它为sftp提供了一个简单的界面..你可以用pysftp做的其他事情很有用:

 data = srv.listdir() # Get the directory and file listing in a list srv.get(file_path) # Download a file from remote server srv.execute('pwd') # Execute a command on the server 

更多的命令和关于PySFTP 在这里 。

扭曲可以帮助你在做什么,检查他们的文档,有很多的例子。 它也是一个成熟的产品,背后有一个大的开发者/用户社区。

您可以使用pexpect模块

这是一个很好的介绍post

 child = pexpect.spawn ('/usr/bin/sftp ' + user@ftp.site.com ) child.expect ('.* password:') child.sendline (your_password) child.expect ('sftp> ') child.sendline ('dir') child.expect ('sftp> ') file_list = child.before child.sendline ('bye') 

我没有testing过,但它应该工作

有一堆提到pysftp的答案,所以如果你想要一个围绕pysftp的上下文pipe理器包装,这里是一个解决scheme,甚至更less的代码,看起来像下面的时候使用

 path = "sftp://user:p@ssw0rd@test.com/path/to/file.txt" # Read a file with open_sftp(path) as f: s = f.read() print s # Write to a file with open_sftp(path, mode='w') as f: f.write("Some content.") 

(完整的)示例: http : //www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

这个上下文pipe理器恰好有自动重试逻辑,当你不能第一次连接的时候(在生产环境中出乎意料的发生的次数比你想象的要多)

上下文pipe理器的要点为open_sftp : https : open_sftp

帕拉米科太慢了。 使用subprocess和shell,这里是一个例子:

 remote_file_name = "filename" remotedir = "/remote/dir" localpath = "/local/file/dir" ftp_cmd_p = """ #!/bin/sh lftp -u username,password sftp://ip:port <<EOF cd {remotedir} lcd {localpath} get {filename} EOF """ subprocess.call(ftp_cmd_p.format(remotedir=remotedir, localpath=localpath, filename=remote_file_name ), shell=True, stdout=sys.stdout, stderr=sys.stderr) 

用RSA密钥然后参考这里

片段:

 import pysftp import paramiko from base64 import decodebytes keydata = b"""L+WsiL5VL51ecJi3LVjmblkAdUTU+xbmXmUArIU5+8N6ua76jO/+T""" key = paramiko.RSAKey(data=decodebytes(keydata)) cnopts = pysftp.CnOpts() cnopts.hostkeys.add(host, 'ssh-rsa', key) with pysftp.Connection(host=host, username=username, password=password, cnopts=cnopts) as sftp: with sftp.cd(directory): sftp.put(file_to_sent_to_ftp)