Python'da SFTP mi? (platform bağımsız)


181

Ben de sabit kodlanmış şifre ile dosyaları sabit kodlu bir konuma transfer basit bir araç üzerinde çalışıyorum. Ben bir python acemi değilim, ama ftplib sayesinde, kolay oldu:

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)

Sorun şu ki, sFTP'yi destekleyen herhangi bir kütüphane bulamıyorum. Böyle bir şeyi güvenli bir şekilde yapmanın normal yolu nedir?

Edit: Buradaki cevaplar sayesinde, Paramiko ile çalıştım ve bu sözdizimi oldu.

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

Tekrar teşekkürler!


1
Teşekkürler ! 5 dakika içinde çalışan bir SFTP yükleme betiği var :)
Ohad Schneider

1
Sadece python ftplib'in TLS en.m.wikipedia.org/wiki/FTPS üzerinden FTPS - ftp'yi desteklediği orijinal soru üzerine genel bir not . FTPS sunucuları, kısmen ssh / sftp'nin her yerde bulunmasından dolayı Unix dünyasında tartışmalı olarak daha az kullanılır, ancak sftp sunucuları, FTPS'nin daha yaygın olduğu Windows ortamında daha az bulunur.
Gnudiff

FTPS desteğinin Python 3.2'ye genişletilmiş bir sınıf kaynağı ile eklendiği anlaşılıyor: sınıf ftplib.FTP_TLS (host = '', kullanıcı = '', passwd = '', acct = '', keyfile = Yok, certfile = Yok, context = Yok, zaman aşımı = Yok, kaynak_adresi = Yok)
mgrollins 21

Yanıtlar:


109

Paramiko , SFTP'yi destekler. Onu kullandım ve Twisted'ı kullandım. Her ikisinin de yeri var, ama Paramiko ile başlamak daha kolay olabilir.


2
yepp, paramiko gitmek için yol (süper kolay kullanım), biraz bağımlılık olan pycrypto windows paketini bulmak zor.
Mauli

Teşekkür ederim. Benioku kurulum talimatları eksikliği nedeniyle paketi nasıl yüklediğini anlamak için biraz zaman aldı ama tam olarak ne ihtiyacım oldu!
Mark Wilbur

15
Jeff Forcier'in ssh'ın eski ve paramiko'nun ileriye dönük olduğunu açıkladığı bitprophet.org/blog/2012/09/29/paramiko-and-ssh adresine bakın .
Christopher Mahan

2
Ayrıca Paramiko'ya dayanan, ancak kullanımı daha kolay olan code.google.com/p/pysftp var
franzlorenzon


78

Pysftp'i kontrol etmelisiniz https://pypi.python.org/pypi/pysftp paramikoya bağlıdır, ancak en yaygın kullanım durumlarını sadece birkaç kod satırına sarar.

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

4
withÖrnekte oy verin
Roman Podlinov

2
pip install pysftp
Bob Stein

2
Bilinen ana bilgisayarlara otomatik olarak yeni sftp ana bilgisayarı ekleme seçeneği var mı?
user443854

1
@ user443854 evet var pysftp.readthedocs.io/en/release_0.2.9/... Ama başka known_host dosyasını ekleyebilir olsa kesinlikle, tavsiye etmem
Aster

15

Kolay ve basit isterseniz, ayrıca bakmak isteyebilirsiniz Fabric . Ruby'nin Capistrano gibi otomatik bir dağıtım aracı, ancak daha basit ve elbette Python için. Paramiko'nun üzerine inşa edilmiştir.

'Otomatik dağıtım' yapmak istemeyebilirsiniz, ancak Fabric kullanım durumunuza mükemmel bir şekilde uymaz. Fabric'in ne kadar basit olduğunu göstermek için: komut dosyanızın fab dosyası ve komutu şu şekilde görünecektir (test edilmedi, ancak% 99 çalışacağından emin):

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

Sonra dosyayı fab komutuyla çalıştırın:

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

Ve işiniz bitti! :)


12

İşte pysftp ve özel anahtar kullanan bir örnek.

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 ve pycrypto kullanan kullanımı kolay bir sftp modülüdür. Sftp için basit bir arayüz sağlar .. Oldukça yararlı pysftp ile yapabileceğiniz diğer şeyler:

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

Daha komutları ve PySFTP hakkında burada .


srv.get(file_path) # Download a file from remote serverdosyayı nereye indirdiğini açıklayabilir misiniz ?
Markus Meskanen

Sizin için yerel olanı denediniz mi?
radtek

Evet ama dosya sisteminde nerede? Her şey başarıyla geçiyor ama dosyayı hiçbir yerden bulamıyorum.
Markus Meskanen

Üzgünüm yerel dir demek istedim. Komut dosyasını ev dizininizden çalıştırmayı ve dosyanın orada olup olmadığını görmeyi deneyin.
radtek


1

RSA Anahtarı ile buraya bakın

Pasaj:

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)

0

Pysftp'den bahseden bir sürü yanıt var, bu yüzden pysftp etrafında bir bağlam yöneticisi sarıcısı istemeniz durumunda, burada kullanıldığında aşağıdakine benzeyen daha az kodlu bir çözüm var

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.") 

(Daha dolgun) örnek: http://www.prschmid.com/2016/09/simple-opensftp-context-manager-for.html

Bu bağlam yöneticisi, ilk kez bağlantı kuramamanız durumunda otomatik yeniden deneme mantığını oluşturuyor (şaşırtıcı bir şekilde bir üretim ortamında beklediğinizden daha sık oluyor ...)

İçerik yöneticisi özeti open_sftp: https://gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515


0

Paramiko çok yavaş. Alt işlem ve kabuk kullanın, işte bir örnek:

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)

Soru "Python" ile ilgilidir. Daha da önemlisi, "Platformdan bağımsız" diyor. Cevabınızın daha hızlı çalışıp çalışmadığını söyleyemem. Belki?
BuvinJ

0

PyFilesystem onun ile sshfs bir seçenektir. Kaputun altında Paramiko kullanır ve üstte daha hoş bir paltform bağımsız arayüz sağlar.

import fs

sf = fs.open_fs("sftp://[user[:password]@]host[:port]/[directory]")
sf.makedir('my_dir')

veya

from fs.sshfs import SSHFS
sf = SSHFS(...

-1

Pexpect modülünü kullanabilirsiniz

İşte iyi bir giriş yazısı

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

Bunu test etmedim ama işe yaramalı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.