Exécuter un script Python local sur un serveur distant
Je débogue un script python qui doit s'exécuter sur ma machine virtuelle. Et, je préfère éditer les scripts localement (en dehors des machines virtuelles). Donc, je trouve que c'est fastidieux à scp
des scripts modifiés sur des machines virtuelles à chaque fois. Quelqu'un peut-il suggérer un moyen efficace?
En particulier, je me demande s'il est possible d'exécuter des scripts python sur PVM distant. Quelque chose comme ça:
python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY
5 réponses
C'est possible en utilisant ssh. Python accepte hyphen ( - ) comme argument pour exécuter l'entrée standard,
cat hello.py | ssh user@192.168.1.101 python -
Exécutez Python --help pour plus d'informations.
Bien que cette question ne soit pas tout à fait nouvelle et qu'une réponse ait déjà été choisie, je voudrais partager une autre approche intéressante.
En utilisant la bibliothèque paramiko - une implémentation Python pure de SSH2 - votre script python peut se connecter à un hôte distant via SSH, copier lui-même (!) à cet hôte, puis exécutez cette copie sur l'hôte distant. Stdin, stdout et stderr du processus distant seront disponibles sur votre script en cours d'exécution local. Donc cette solution est à peu près indépendante d'un IDE.
Sur ma machine locale, j'exécute le script avec un paramètre cmd-line 'deploy', qui déclenche l'exécution à distance. Sans un tel paramètre, le code réel destiné à l'hôte distant est exécuté.
import sys
import os
def main():
print os.name
if __name__ == '__main__':
try:
if sys.argv[1] == 'deploy':
import paramiko
# Connect to remote host
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('remote_hostname_or_IP', username='john', password='secret')
# Setup sftp connection and transmit this script
sftp = client.open_sftp()
sftp.put(__file__, '/tmp/myscript.py')
sftp.close()
# Run the transmitted script remotely without args and show its output.
# SSHClient.exec_command() returns the tuple (stdin,stdout,stderr)
stdout = client.exec_command('python /tmp/myscript.py')[1]
for line in stdout:
# Process each line in the remote output
print line
client.close()
sys.exit(0)
except IndexError:
pass
# No cmd-line args provided, run script normally
main()
La gestion des exceptions est laissée de côté pour simplifier cet exemple. Dans les projets avec plusieurs fichiers de script, vous devrez probablement placer tous ces fichiers (et autres dépendances) sur l'hôte distant.
ssh user@machine python < script.py - arg1 arg2
Parce que cat |
n'est généralement pas nécessaire
Vous pouvez le faire via ssh.
ssh user@192.168.1.101 "python ./hello.py"
Vous pouvez également modifier le script en ssh à l'aide d'un éditeur de texte ou d'un transfert X11.
J'ai dû le faire avant D'utiliser Paramiko dans un cas où je voulais exécuter un script PyQt4 local dynamique sur un hôte exécutant un serveur ssh qui a connecté mon serveur OpenVPN et demander leur préférence de routage (Split tunneling).
Tant que le serveur ssh auquel vous vous connectez a toutes les dépendances requises de votre script (PyQt4 dans mon cas), vous pouvez facilement encapsuler les données en les encodant en base64 et utiliser la fonction intégrée exec()
sur le message décodé. Si Je rappelez-vous correctement mon one-liner pour cela était:
stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]
C'est difficile à lire et vous devez échapper aux séquences d'échappement car elles sont interprétées deux fois (une fois par l'expéditeur, puis de nouveau par le récepteur). Il peut également avoir besoin d'un débogage, j'ai emballé mon serveur sur des PC ou je référencerais simplement mon script de routage OpenVPN.
La différence en le faisant de cette façon par opposition à l'envoi d'un fichier est qu'il ne touche jamais le disque sur le serveur et est exécuté directement à partir de la mémoire (sauf si sûr, ils journal de la commande). Vous constaterez que l'encapsulation d'informations de cette façon (bien qu'inefficace) peut vous aider à regrouper les données dans un seul fichier.
Par exemple, vous pouvez utiliser cette méthode pour inclure des données brutes de dépendances externes (c'est à dire une image) dans votre script principal.