123

ローカルマシンに、cronで実行される毎日のPythonスクリプトによって生成されたテキストファイルがあります。

そのファイルをSSH経由でサーバーに安全に送信するためのコードを少し追加したいと思います。

4

14 に答える 14

167

Paramikoライブラリを使用して Python でこれを行う (つまり、subprocess.Popen などを介して scp をラップしない) には、次のようにします。

import os
import paramiko

ssh = paramiko.SSHClient() 
ssh.load_host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username=username, password=password)
sftp = ssh.open_sftp()
sftp.put(localpath, remotepath)
sftp.close()
ssh.close()

(おそらく、不明なホスト、エラー、必要なディレクトリの作成などに対処する必要があるでしょう)。

于 2008-09-16T05:27:59.390 に答える
64

次のコマンドを使用してbashコマンドを呼び出すことができます( SSHscp経由でファイルをコピーします)。subprocess.run

import subprocess
subprocess.run(["scp", FILE, "USER@SERVER:PATH"])
#e.g. subprocess.run(["scp", "foo.bar", "joe@srvr.net:/path/to/foo.bar"])

同じPythonプログラムで送信するファイルを作成する場合は、ファイルを開くために使用しているブロックsubprocess.runの外側でコマンドを呼び出す必要があります(または、ファイルを使用していない場合は、最初にファイルを呼び出します。ブロック)、Pythonからディスクにフラッシュされていることがわかります。with.close()with

scpがパブリックsshキーで自動的に認証されるように(つまり、スクリプトがパスワードを要求しないように)、事前にsshキーを生成(ソースマシン上)およびインストール(宛先マシン上)する必要があります。 。

于 2008-09-16T00:55:43.850 に答える
33

おそらくサブプロセスモジュールを使用するでしょう。このようなもの:

import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)

destinationおそらくフォームはどこにありますかuser@remotehost:remotepathshell=Trueパスの空白を処理しないscp操作を指定するために単一の文字列引数を使用した元の回答の弱点を指摘してくれた@CharlesDuffyに感謝します。

モジュールのドキュメントには、この操作と組み合わせて実行する可能性のあるエラーチェックの例が含まれています。

マシン間で無人のパスワードなしのscpを実行できるように、適切な資格情報を設定していることを確認してください。これにはすでにstackoverflowの質問があります。

于 2008-09-16T00:58:49.473 に答える
13

問題にアプローチするには、いくつかの異なる方法があります。

  1. コマンドライン プログラムをラップする
  2. SSH 機能を提供する Python ライブラリを使用する (例 - ParamikoまたはTwisted Conch )

各アプローチには独自の癖があります。「ssh」、「scp」、「rsync」などのシステム コマンドをラップする場合は、パスワードなしのログインを有効にするために SSH キーをセットアップする必要があります。Paramiko やその他のライブラリを使用してスクリプトにパスワードを埋め込むことができますが、特に SSH 接続の基本 (キー交換、エージェントなど) に慣れていない場合は、ドキュメントがないことに不満を感じるかもしれません。言うまでもなく、ほとんどの場合、この種のパスワードよりも SSH キーの方が優れています。

注: SSH 経由でファイルを転送することを計画している場合、特に代替手段が単純な古い scp である場合、rsync に勝るものはありません。

私はシステム コールを置き換える目的で Paramiko を使用しましたが、使いやすさとすぐに慣れることができたので、ラップされたコマンドに引き戻されました。あなたは違うかもしれません。少し前にコンクにやり直したけど、気に入らなかった。

システム コール パスを選択する場合、Python は os.system や commands/subprocess モジュールなどの一連のオプションを提供します。バージョン 2.4 以降を使用している場合は、subprocess モジュールを使用します。

于 2008-09-16T01:32:08.070 に答える
6

ホストキーのチェックも処理するために、このようなことを行うことができます

import os
os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")
于 2019-07-02T10:16:23.637 に答える
4

fabricssh 経由でファイルをアップロードするために使用できます。

#!/usr/bin/env python
from fabric.api import execute, put
from fabric.network import disconnect_all

if __name__=="__main__":
    import sys
    # specify hostname to connect to and the remote/local paths
    srcdir, remote_dirname, hostname = sys.argv[1:]
    try:
        s = execute(put, srcdir, remote_dirname, host=hostname)
        print(repr(s))
    finally:
        disconnect_all()
于 2014-03-28T10:41:18.170 に答える
0

非常に単純なアプローチは次のとおりです。

import os
os.system('sshpass -p "password" scp user@host:/path/to/file ./')

Python ライブラリは必要なく (os のみ)、動作しますが、この方法を使用するには別の ssh クライアントをインストールする必要があります。これを別のシステムで実行すると、望ましくない動作が発生する可能性があります。

于 2018-01-04T15:40:07.140 に答える
-3

ちょっとハッキーですが、以下はうまくいくはずです:)

import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" user@myserver.com:"+serverPath)
于 2008-09-16T00:56:31.070 に答える