سؤال

أنا أعمل على أداة بسيطة تنقل الملفات إلى موقع مشفر بكلمة مرور مشفرة أيضًا.أنا مبتدئ في لغة بايثون، ولكن بفضل 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. لقد استعملت، ولقد استعملت ملتوية. كلا يكون لها مكانها، ولكن قد تجد أنه من الأسهل أن تبدأ مع 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.'

إذا كنت تريد سهلة وبسيطة، قد ترغب أيضا أن ننظر إلى نسيج . إنها أداة التوزيع الآلي مثل كابيسترانو روبي، ولكن أبسط وبالطبع لبيثون. انها بناء على رأس Paramiko.

وأنت قد لا تريد أن تفعل "نشر الآلي" ولكن نسيج تناسب حالة استخدامك أيا تماما أقل. لتبين لكم كيف نسيج بسيط هو: أن ملف القوات المسلحة البوروندية والأوامر لالسيناريو الخاص بك تبدو هذه (لم تختبر، ولكن 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 -f fab_putfile.py put_file:file=./path/to/my/file

ولقد انتهيت! :)

وهنا هو عينة باستخدام 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 هو وسيلة سهلة لاستخدام وحدة بالنشر التي تستخدم 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 حدة

هنا هو مقدمة جيدة آخر

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')

وأنا لم تختبر هذا ولكن يجب أن تعمل

وParamiko بطيء جدا. استخدام فرعي أو جانبي وشركة شل، وهنا مثال:

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)

هناك مجموعة من الإجابات التي تشير إلى pysftp، لذلك في حالة رغبتك في الحصول على غلاف مدير سياق حول pysftp، فإليك حلًا أقل رمزًا ينتهي به الأمر إلى الظهور كما يلي عند استخدامه

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

يحدث أن يحتوي مدير السياق هذا على منطق إعادة المحاولة التلقائية في حالة عدم تمكنك من الاتصال في المرة الأولى (وهو ما يحدث بشكل مدهش في كثير من الأحيان أكثر مما تتوقع في بيئة الإنتاج ...)

جوهر مدير السياق ل open_sftp: https://Gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top