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)