Frage

Ich habe eine Textdatei auf meinem lokalen Rechner, die von einem täglichen Python-Skript in cron erzeugt wird.

Ich möchte ein Stück Code hinzufügen, dass die Datei sicher über SSH auf meinen Server geschickt zu haben.

War es hilfreich?

Lösung

Wenn Sie den einfachen Ansatz wollen, sollte diese Arbeit.

Sie wollen „.close ()“ die Datei zuerst, so dass Sie wissen, dass es auf der Festplatte aus Python gerötet ist.

import os
os.system("scp FILE USER@SERVER:PATH")
#e.g. os.system("scp foo.bar joe@srvr.net:/path/to/foo.bar")

Sie müssen (auf der Quellmaschine) erzeugen und installieren (auf der Zielmaschine) einen SSH-Schlüssel voraus, so dass die scp automatisch mit Ihrem öffentlichen SSH-Schlüssel (mit anderen Worten authentifiziert werden, so dass Ihr Skript fragt nicht nach ein Passwort).

ssh-keygen Beispiel

Andere Tipps

das in Python zu tun (dh nicht scp durch subprocess.Popen Einwickeln oder ähnliches) mit dem paramiko Bibliothek, würden Sie so etwas tun:

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

(Sie würden wahrscheinlich mit unbekanntem Hosts, Fehlern umgehen wollen, die Schaffung alle Verzeichnisse erforderlich, und so weiter).

Sie würden wahrscheinlich verwenden die Subprozess Modul . So etwas wie folgt aus:

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

Wo destination ist wahrscheinlich die Form user@remotehost:remotepath. Dank an @Charles Duffy für die Schwäche in meiner ursprünglichen Antwort darauf hingewiesen, die ein einzelnes String-Argument verwendet, um den scp Betrieb shell=True angeben -., Dass keine Leerzeichen in Pfaden umgehen würde

Die Modul Dokumentation hat Beispiele für die Fehlerprüfung, dass Sie in Verbindung mit diesem Vorgang auszuführen mögen .

Stellen Sie sicher, dass Sie die richtigen Anmeldeinformationen eingerichtet haben, so dass Sie eine durchführen können unbeaufsichtigt, passwordless scp zwischen der Maschinen . Es ist eine Stackoverflow Frage für diesen bereits .

Es gibt ein paar verschiedene Möglichkeiten, um das Problem zu nähern:

  1. Wrap Befehlszeilenprogramme
  2. verwenden, um eine Python-Bibliothek, die SSH-Funktionen (zB bietet - paramiko oder Verdrehte Conch )

Jeder Ansatz hat seine eigenen Macken. Sie werden auf Setup SSH-Schlüssel benötigen kennwort weniger Anmeldungen zu aktivieren, wenn Sie Systembefehle wie „ssh“ wickeln „scp“ oder „rsync“. Sie können ein Passwort in einem Skript einbetten paramiko oder eine andere Bibliothek, aber Sie könnten den Mangel an Dokumentation frustrierend, vor allem, wenn Sie nicht vertraut ist mit den Grundlagen der SSH-Verbindung finden (zB - Schlüsselaustausch, Agenten, etc). Es geht wohl selbstverständlich, dass SSH-Schlüssel sind fast immer eine bessere Idee, als Passwörter für diese Art von Sachen.

. Hinweis: es ist schwer rsync zu schlagen, wenn Sie auf die Übertragung von Dateien über SSH planen, vor allem, wenn die alternative plain old scp ist

Ich habe zum Ersatz der Systemaufrufe paramiko mit einem Auge verwendet, sondern fand ich wieder auf die eingewickelt Befehle aufgrund ihrer Benutzerfreundlichkeit und sofortiger Vertrautheit gezogen. Sie könnten unterschiedlich sein. Ich habe die Conch einmal über einige Zeit her, aber es hat mich nicht an.

für das System-Call-Pfad Wenn entscheiden, bietet Python eine Reihe von Optionen wie os.system oder die Befehle / subprocess Module. Ich würde mit dem Subprozess Modul gehen, wenn Version mit 2.4 +.

das gleiche Problem erreicht, aber anstelle von "Hacking" oder emuliert Befehlszeile:

Sie haben diese Antwort hier .

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

fabric verwendet werden könnte, um Dateien hochladen über ssh:

#!/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()

Sie können die Vasallen Paket verwenden, die genau für diese ausgelegt ist.

Alles, was Sie brauchen, ist Vasall zu installieren und tun

from vassal.terminal import Terminal
shell = Terminal(["scp username@host:/home/foo.txt foo_local.txt"])
shell.run()

Auch sie sparen Sie Berechtigungsnachweis authentifizieren und müssen sie nicht immer wieder eingeben.

Der Aufruf scp Befehl über subprocess erlaubt nicht den Fortschrittsbericht im Skript zu erhalten. pexpect verwendet werden könnte, dass Informationen zu extrahieren:

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

Siehe Python Datei kopiert in lokalem Netzwerk (linux -> linux)

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

Ich benutzen sshfs das Remote-Verzeichnis über ssh zu montieren, und shutil die Dateien kopieren:

$ mkdir ~/sshmount
$ sshfs user@remotehost:/path/to/remote/dst ~/sshmount

Dann in Python:

import shutil
shutil.copy('a.txt', '~/sshmount')

Diese Methode hat den Vorteil, dass Sie Daten über streamen können, wenn Sie Daten erzeugt werden, anstatt lokal zwischenspeichern und eine einzige große Datei zu senden.

Versuchen Sie dies, wenn Sie wan't SSL-Zertifikate verwenden:

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

ein sehr einfacher Ansatz ist die folgende:

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

keine Python-Bibliothek erforderlich sind (nur os) und es funktioniert

Art hacky, aber die folgenden funktionieren sollte:)

import os
filePath = "/foo/bar/baz.py"
serverPath = "/blah/boo/boom.py"
os.system("scp "+filePath+" user@myserver.com:"+serverPath)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top