PythonのSFTP?(プラットフォーム非依存)


181

私は、パスワードもハードコーディングされたハードコーディングされた場所にファイルを転送するシンプルなツールに取り組んでいます。私は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.'

再度、感謝します!


1
よろしくお願いします!5分で動作するSFTPアップロードスクリプトを入手しました:)
Ohad Schneider

1
python ftplibが FTPS-TLS over ftp en.m.wikipedia.org/wiki/FTPSもサポートしているという、元の質問に関する一般的なメモ 。FTPSサーバーは、おそらくssh / sftpの存在が原因で、Unixの世界ではほとんど使用されていませんが、FTPSがより一般的なWindows環境では、sftpサーバーの存在ははるかに少なくなっています。
Gnudiff 2017年

FTPSサポートが拡張されたクラスソースを使用してPython 3.2で追加されたようです:クラスftplib.FTP_TLS(host = ''、user = ''、passwd = ''、acct = ''、keyfile = None、certfile = None、context =なし、タイムアウト=なし、source_address =なし)
mgrollins

回答:


109

ParamikoはSFTPをサポートしています。私はそれを使用し、ツイストを使用しました。どちらにも場所がありますが、Paramikoを使い始める方が簡単な場合があります。


2
うん、paramikoは行く方法です(超使いやすい)、依存関係であるpycryptoのwindowsパッケージを見つけるのは少しトリッキーです。
Mauli

ありがとうございました。readmeにインストール手順がないため、パッケージのインストール方法を理解するのに少し時間がかかりましたが、まさにそれが必要でした!
Mark Wilbur、

15
bitprophet.org/blog/2012/09/29/paramiko-and-sshを参照してください。JeffForcierが、sshは時代遅れであり、paramikoが将来への道だと説明しています。
クリストファーマーハン2012

2
Paramikoに基づいているが使いやすいcode.google.com/p/pysftp もあります
franzlorenzon


78

params に依存するpysftp https://pypi.python.org/pypi/pysftpを確認する必要がありますが、ほとんどの一般的な使用例を数行のコードにラップしています。

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例に
ローマPodlinov

2
pip install pysftp
Bob Stein

2
既知のホストに新しいsftpホストを自動的に追加するオプションはありますか?
user443854

1
@ user443854はいありpysftp.readthedocs.io/en/release_0.2.9/...しかし、あなたは別のknown_hostファイルを追加できますが、私は間違いなく、それをお勧めしません
ASTER

15

簡単でシンプルにしたい場合は、Fabricご覧ください。RubyのCapistranoのような自動化されたデプロイメントツールですが、Pythonよりもシンプルで、もちろんです。パラミコの上に構築されています。

「自動デプロイメント」を行いたくないかもしれませんが、Fabricはそれでもなおユースケースに完全に適合します。ファブリックがいかに単純であるかを示すために、スクリプトのfabファイルとコマンドは次のようになります(テストされていませんが、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

これで完了です。:)


12

以下は、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モジュールです。それはsftpへのシンプルなインターフェースを提供します。

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についてはこちら


srv.get(file_path) # Download a file from remote serverファイルをダウンロードする場所を説明できますか?
Markus Meskanen 2017年

実行したローカルを試してみましたか?
radtek、2017

ええ、でもファイルシステムのどこに?すべてが正常に実行されましたが、どこからでもファイルを見つけることができません。
Markus Meskanen 2017

すみません、私はローカルディレクトリを意味していました。ホームディレクトリからスクリプトを実行して、ファイルが存在するかどうかを確認してください。
radtek、2017

3

Twistedはあなたがやっていることを手助けすることができます。彼らのドキュメントをチェックしてください。たくさんの例があります。また、大きな開発者/ユーザーコミュニティを備えた成熟した製品です。



1

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)

0

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_sftphttps : //gist.github.com/prschmid/80a19c22012e42d4d6e791c1e4eb8515


0

パラミコはとても遅いです。サブプロセスとシェルを使用します。以下に例を示します。

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)

問題は「Python」に関するものです。これは一般に、その中にとどまることを意味します-特にそうするための非常に多くのオプションがある場合。さらに重要なのは、「プラットフォームに依存しない」ということです。あなたの答えが速くなるかどうかは言えません。たぶん?
BuvinJ

0

sshfs含むPyFilesystemは1つのオプションです。これは内部でParamikoを使用し、上部により優れた独立型のインターフェースを提供します。

import fs

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

または

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

-1

あなたは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')

私はこれをテストしていませんが、うまくいくはずです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.