web-dev-qa-db-fra.com

Exécuter un script python local sur un serveur distant

Je suis en train de déboguer un script python qui doit être exécuté sur ma machine virtuelle. Et, je préfère éditer les scripts localement (en dehors des machines virtuelles). Je trouve donc que c'est fastidieux à scp modifier les scripts aux 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 un PVM distant. Quelque chose comme ca:

python --remote [email protected] hello.py //**FAKED**, served to explain ONLY
24
qweruiop

Il est possible d'utiliser ssh. Python accepte le trait d'union (-) comme argument pour exécuter l'entrée standard,

cat hello.py | ssh [email protected] python -

Exécutez python --help pour plus d’informations.

44
asdfg

Bien que cette question ne soit pas tout à fait nouvelle et qu'une réponse ait déjà été choisie, j'aimerais partager une autre approche de Nice.

En utilisant paramiko library - une implémentation pure de SSH2 en python - votre script python peut se connecter à un hôte distant via SSH, se copier (!) Sur cet hôte, puis exécuter cette copie sur cet hôte. 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 le 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 __== '__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 comportant plusieurs fichiers de script, vous devrez probablement placer tous ces fichiers (et autres dépendances) sur l'hôte distant.

33
Andreas N
ssh user@machine python < script.py - arg1 arg2

Parce que cat | n'est généralement pas nécessaire 

10
neric

Vous pouvez le faire via ssh.

ssh [email protected] "python ./hello.py"

Vous pouvez également éditer le script en ssh en utilisant un éditeur de texte ou un transfert X11.

4
smeso

Je devais le faire avant d'utiliser Paramiko dans le cas où je souhaitais exécuter un script PyQt4 local et dynamique sur un hôte exécutant un serveur ssh ayant connecté mon serveur OpenVPN et demandant leur préférence de routage (tunneling fractionné).

Tant que le serveur ssh auquel vous vous connectez possède 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 me souviens bien, mon one-liner était:

stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]

Il 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 et une autre fois par le destinataire). Il faudra peut-être aussi un peu de débogage. J'ai emballé mon serveur sur PCS ou je viens de référencer mon script de routage OpenVPN.

La différence avec l'envoi d'un fichier est que, de cette manière, il ne touche jamais le disque sur le serveur et est exécuté directement à partir de la mémoire (à moins bien sûr qu'ils enregistrent la commande). Vous constaterez que l'encapsulation des informations de cette manière (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 provenant de dépendances externes (c'est-à-dire une image) dans votre script principal.

0
alisenby94