ローカルマシンに、cronで実行される毎日のPythonスクリプトによって生成されるテキストファイルがあります。
そのファイルをSSH経由でサーバーに安全に送信するためのコードを少し追加したいと思います。
シンプルなアプローチが必要な場合は、これでうまくいくはずです。
Pythonからディスクにフラッシュされていることがわかるように、最初にファイルを「.close()」する必要があります。
import os
os.system("scp FILE USER@SERVER:PATH")
#e.g. os.system("scp foo.bar [email protected]:/path/to/foo.bar")
Scpが公開sshキーで自動的に認証されるように(つまり、スクリプトがパスワードを要求しないように)、事前にsshキーを生成(ソースマシン上)およびインストール(宛先マシン上)する必要があります。
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()
(おそらく、不明なホスト、エラー、必要なディレクトリの作成などに対処したいと思うでしょう)。
おそらく subprocess module を使用するでしょう。このようなもの:
import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)
destination
はおそらくuser@remotehost:remotepath
の形式です。元の回答の弱点を指摘してくれた@Charles Duffyに感謝します。これは、単一の文字列引数を使用してscp操作Shell=True
を指定しました。パスの空白は処理しません。
モジュールのドキュメントには、 この操作と組み合わせて実行するエラーチェックの例 があります。
マシン間の無人、パスワードなしのscp を実行できるように、適切な資格情報を設定したことを確認してください。 これに関するstackoverflowの質問 があります。
問題にアプローチする方法はいくつかあります。
各アプローチには独自の癖があります。 「ssh」、「scp」、「rsync」などのシステムコマンドをラップする場合は、パスワードなしのログインを有効にするためにSSHキーをセットアップする必要があります。 Paramikoまたは他のライブラリを使用してスクリプトにパスワードを埋め込むことができますが、特にSSH接続の基本(たとえば、キー交換、エージェントなど)に慣れていない場合は、ドキュメントが不足していることがわかります。おそらく、SSHキーの方がこの種のパスワードよりも常に優れたアイデアであることは言うまでもないでしょう。
注:SSH経由でファイルを転送する場合、特に代替手段が単純な古いscpである場合は、rsyncに勝るものはありません。
システムコールの置き換えに目を向けてParamikoを使用しましたが、使いやすさとすぐに慣れたために、ラップされたコマンドに引き戻されました。あなたは違うかもしれません。しばらく前にコンクをもう一度やりましたが、それは私にはアピールしませんでした。
システムコールパスを選択する場合、Pythonはos.systemやコマンド/サブプロセスモジュールなどのオプションの配列を提供します。バージョン2.4+を使用している場合は、サブプロセスモジュールを使用します。
同じ問題に到達しましたが、コマンドラインを「ハッキング」またはエミュレートする代わりに:
この答えを見つけました here 。
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')
ホストキーチェックも処理するために、このようなことをすることができます
import os
os.system("sshpass -p password scp -o StrictHostKeyChecking=no local_file_path username@hostname:remote_path")
このために設計されたvassalパッケージを使用できます。
必要なのは、vassalをインストールして
from vassal.terminal import Terminal
Shell = Terminal(["scp username@Host:/home/foo.txt foo_local.txt"])
Shell.run()
また、認証情報が保存されるため、何度も入力する必要がありません。
外部リソースparamikoを使用します。
from paramiko import SSHClient
from scp import SCPClient
import os
ssh = SSHClient()
ssh.load_Host_keys(os.path.expanduser(os.path.join("~", ".ssh", "known_hosts")))
ssh.connect(server, username='username', password='password')
with SCPClient(ssh.get_transport()) as scp:
scp.put('test.txt', 'test2.txt')
非常に簡単なアプローチは次のとおりです。
import os
os.system('sshpass -p "password" scp user@Host:/path/to/file ./')
pythonライブラリは不要(osのみ)で、動作します
SSL証明書を使用したくない場合は、これを試してください。
import subprocess
try:
# Set scp and ssh data.
connUser = 'john'
connHost = 'my.Host.com'
connPath = '/home/john/'
connPrivateKey = '/home/user/myKey.pem'
# Use scp to send file from local to Host.
scp = subprocess.Popen(['scp', '-i', connPrivateKey, 'myFile.txt', '{}@{}:{}'.format(connUser, connHost, connPath)])
except CalledProcessError:
print('ERROR: Connection to Host failed!')
サブプロセス経由でscp
コマンドを呼び出すと、スクリプト内で進行状況レポートを受信できません。 pexpect
を使用して、その情報を抽出できます。
import pipes
import re
import pexpect # $ pip install pexpect
def progress(locals):
# extract percents
print(int(re.search(br'(\d+)%$', locals['child'].after).group(1)))
command = "scp %s %s" % Tuple(map(pipes.quote, [srcfile, destination]))
pexpect.run(command, events={r'\d+%': progress})
ローカルネットワークのPythonコピーファイル(linux-> linux) を参照してください