J'ai un fichier texte sur ma machine locale qui est généré par un script quotidien exécuté dans cron.
Je voudrais ajouter un peu de code pour que ce fichier soit envoyé en toute sécurité à mon serveur via SSH.
J'ai un fichier texte sur ma machine locale qui est généré par un script quotidien exécuté dans cron.
Je voudrais ajouter un peu de code pour que ce fichier soit envoyé en toute sécurité à mon serveur via SSH.
Pour faire cela en Python (c'est-à-dire sans faire passer scp par subprocess.Popen ou similaire) avec la commande Paramiko bibliothèque, vous feriez quelque chose comme ça :
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()
(Vous voudrez probablement traiter les hôtes inconnus, les erreurs, la création de tous les répertoires nécessaires, et ainsi de suite).
paramiko dispose également d'une belle fonction sftp.put(self, localpath, remotepath, callback=None), ce qui vous évite d'avoir à ouvrir, écrire et fermer chaque fichier.
Vous pouvez appeler le scp
bash (il copie les fichiers sur SSH ) avec 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"])
Si vous créez le fichier que vous voulez envoyer dans le même programme Python, vous voudrez appeler subprocess.run
en dehors du with
que vous utilisez pour ouvrir le fichier (ou appelez le bloc .close()
sur le fichier d'abord si vous n'utilisez pas un fichier with
), de sorte que vous savez qu'il est transféré sur le disque depuis Python.
Vous devez générer (sur la machine source) et installer (sur la machine de destination) une clé ssh au préalable afin que le scp soit automatiquement authentifié avec votre clé ssh publique (en d'autres termes, afin que votre script ne demande pas de mot de passe).
@CharlesDuffy : subprocess.check_call(['scp', srcfile, dest])
peut être utilisé depuis Python 2.5 à la place de rc = Popen(..).wait(); if rc != 0: raise ..
Vous utiliseriez probablement le module de sous-processus . Quelque chose comme ça :
import subprocess
p = subprocess.Popen(["scp", myfile, destination])
sts = os.waitpid(p.pid, 0)
Où destination
est probablement de la forme user@remotehost:remotepath
. Merci à @Charles Duffy pour avoir souligné la faiblesse de ma réponse originale, qui utilisait un seul argument de type chaîne pour spécifier l'opération scp. shell=True
- qui ne gère pas les espaces dans les chemins.
La documentation du module a des exemples de vérification d'erreurs que vous pourriez vouloir effectuer en conjonction avec cette opération.
Assurez-vous que vous avez mis en place les informations d'identification appropriées afin de pouvoir effectuer une vérification de l'identité de la personne. scp sans surveillance et sans mot de passe entre les machines. . Il existe un question de stackoverflow pour cela déjà .
Utiliser subprocess.Popen est la bonne chose. Lui passer une chaîne plutôt qu'un tableau (et utiliser shell=True) est la mauvaise chose, car cela signifie que les noms de fichiers avec des espaces ne fonctionnent pas correctement.
Il existe plusieurs façons d'aborder le problème :
Chaque approche a ses propres particularités. Vous devrez configurer des clés SSH pour permettre des connexions sans mot de passe si vous enveloppez des commandes système comme "ssh", "scp" ou "rsync". Vous pouvez intégrer un mot de passe dans un script en utilisant Paramiko ou une autre bibliothèque, mais vous pourriez trouver le manque de documentation frustrant, surtout si vous n'êtes pas familier avec les bases de la connexion SSH (par exemple - échanges de clés, agents, etc). Il va probablement sans dire que les clés SSH sont presque toujours une meilleure idée que les mots de passe pour ce genre de choses.
NOTE : il est difficile de battre rsync si vous prévoyez de transférer des fichiers via SSH, surtout si l'alternative est le bon vieux scp.
J'ai utilisé Paramiko dans le but de remplacer les appels système, mais j'ai été attiré par les commandes enveloppées en raison de leur facilité d'utilisation et de leur familiarité immédiate. Vous êtes peut-être différent. J'ai jeté un coup d'oeil à Conch il y a quelque temps, mais il ne m'a pas séduit.
Si vous optez pour le chemin de l'appel système, Python offre un éventail d'options telles que os.system ou les modules commands/subprocess. J'opterais pour le module subprocess si vous utilisez la version 2.4+.
J'ai rencontré le même problème, mais au lieu de "pirater" ou d'émuler la ligne de commande :
J'ai trouvé cette réponse ici .
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')
Note - ceci repose sur le paquet scp. En décembre 2017, la dernière mise à jour de ce paquet date de 2015 et le numéro de version est 0.1.x. Je ne suis pas sûr de vouloir ajouter cette dépendance.
Nous sommes donc en 2018 et la version 0.11.0 est sortie en mai. Donc, il semble que SCPClient n'est pas mort après tout ?
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.