web-dev-qa-db-ja.com

Pythonでscpする方法は?

Pythonでファイルをscpする最もPython的な方法は何ですか?私が知っている唯一のルートは

os.system('scp "%s" "%s:%s"' % (localfile, remotehost, remotefile) )

これはハックであり、Linuxのようなシステムの外では機能せず、リモートホストにパスワードなしのSSHが設定されていない限り、パスワードプロンプトを回避するためにPexpectモジュールの支援が必要です。

Twistedのconchは知っていますが、低レベルのsshモジュールを介して自分でscpを実装することは避けたいです。

paramiko、sshとsftpをサポートするPythonモジュールを知っています。しかし、それはscpをサポートしていません。

背景:sftpをサポートしていないがssh/scpをサポートしているルーターに接続しているため、sftpはオプションではありません。

EDIT:これは SCPを使用してPythonのリモートサーバーにファイルをコピーする方法またはSSH?ただし、、その質問は、Python内からのキーを扱うscp固有の回答を与えません。私はコードのようなものを実行する方法を望んでいます

import scp

client = scp.Client(Host=host, user=user, keyfile=keyfile)
# or
client = scp.Client(Host=host, user=user)
client.use_system_keys()
# or
client = scp.Client(Host=host, user=user, password=password)

# and then
client.transfer('/etc/local/filename', '/etc/remote/filename')
142

モジュールをお試しください paramiko_scp 。使い方はとても簡単です。次の例を参照してください。

import paramiko
from scp import SCPClient

def createSSHClient(server, port, user, password):
    client = paramiko.SSHClient()
    client.load_system_Host_keys()
    client.set_missing_Host_key_policy(paramiko.AutoAddPolicy())
    client.connect(server, port, user, password)
    return client

ssh = createSSHClient(server, port, user, password)
scp = SCPClient(ssh.get_transport())

次にscp.get()またはscp.put()を呼び出してscp操作を実行します。

SCPClientコード

87
Tom Shen

Pexpectソースコード )を試すことに興味があるかもしれません。これにより、パスワードの対話型プロンプトに対処できます。

メインWebサイトからの使用例(ftpの場合)の抜粋を次に示します。

# This connects to the openbsd ftp site and
# downloads the recursive directory listing.
import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('[email protected]')
child.expect ('ftp> ')
child.sendline ('cd pub')
child.expect('ftp> ')
child.sendline ('get ls-lR.gz')
child.expect('ftp> ')
child.sendline ('bye')
13
Pat Notz

paramiko も確認できます。 scpモジュールは(まだ)ありませんが、sftpを完全にサポートしています。

[編集]申し訳ありませんが、paramikoに言及した行を見逃しました。次のモジュールは、paramikoのscpプロトコルの単なる実装です。 paramikoまたはconch(Pythonで知っている唯一のssh実装)を使用したくない場合は、パイプを使用して通常のsshセッションで実行するようにこれを修正できます。

paramikoの場合はscp.py

10
JimB

win32にPuTTYをインストールすると、pscp(PuTTY scp)が取得されます。

したがって、win32でもos.systemハックを使用できます。

(そして、鍵管理にPuTTYエージェントを使用できます)


申し訳ありませんが、ハックにすぎません(ただし、pythonクラスでラップできます)

6
Blauohr

まっすぐな答えを見つけることができず、この「scp.Client」モジュールは存在しません。代わりに、 this が適しています:

from paramiko import SSHClient
from scp import SCPClient

ssh = SSHClient()
ssh.load_system_Host_keys()
ssh.connect('example.com')

with SCPClient(ssh.get_transport()) as scp:
   scp.put('test.txt', 'test2.txt')
   scp.get('test2.txt')
6
Maviles

fabric.transfer をご覧ください。

from fabric import Connection

with Connection(Host="hostname", 
                user="admin", 
                connect_kwargs={"key_filename": "/home/myuser/.ssh/private.key"}
               ) as c:
    c.get('/foo/bar/file.txt', '/tmp/')
4
user443854

この質問が聞かれてからかなりの時間が経ちましたが、その間、これを処理できる別のライブラリが作成されました。 Plumbum に含まれる copy 関数を使用できます=ライブラリ:

import plumbum
r = plumbum.machines.SshMachine("example.net")
   # this will use your ssh config as `ssh` from Shell
   # depending on your config, you might also need additional
   # params, eg: `user="username", keyfile=".ssh/some_key"`
fro = plumbum.local.path("some_file")
to = r.path("/path/to/destination/")
plumbum.path.utils.copy(fro, to)
4
pmos

パッケージサブプロセスとコマンドコールを使用して、シェルからscpコマンドを使用できます。

from subprocess import call

cmd = "scp [email protected]:files [email protected]:files"
call(cmd.split(" "))
4
user7529863

今日の時点で、おそらく最良の解決策はAsyncSSHです

https://asyncssh.readthedocs.io/en/latest/#scp-client

async with asyncssh.connect('Host.tld') as conn:
    await asyncssh.scp((conn, 'example.txt'), '.', recurse=True)
2
Loïc

しばらく前に、paramikoに依存するpython SCPコピースクリプトを作成しました。パスワード認証へのフォールバックを使用して、秘密鍵またはSSH鍵エージェントとの接続を処理するコードが含まれています。

http://code.activestate.com/recipes/576810-copy-files-over-ssh-using-paramiko/

1
ccpizza

* nixを使用している場合は、 sshpass を使用できます

sshpass -p password scp -o User=username -o StrictHostKeyChecking=no src dst:/path
1
user178047

うーん、おそらく別のオプションは sshfs のようなものを使用することでしょう(Macでも sshfs があります)。ルーターをマウントしたら、ファイルを完全にコピーできます。それがあなたの特定のアプリケーションで機能するかどうかはわかりませんが、便利な解決策です。

1
Pat Notz