Запуск локального скрипта python на удаленном сервере


Я отлаживаю какой-то скрипт python, который должен работать на моей виртуальной машине. И я предпочитаю редактировать сценарии локально (вне виртуальных машин). Поэтому я считаю, что утомительно scp каждый раз изменять скрипты для виртуальных машин. Может кто-нибудь подсказать какой-то эффективный способ?

В частности, мне интересно, можно ли выполнять скрипты python на удаленном PVM. Что-то вроде этого:

python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY
5 21

5 ответов:

Это возможно с помощью ssh. Python принимает дефис(-) в качестве аргумента для выполнения стандартного ввода,

cat hello.py | ssh user@192.168.1.101 python -

Запуститеpython --help для получения дополнительной информации.

Хотя этот вопрос не совсем новый, и ответ уже был выбран, я хотел бы поделиться другим хорошим подходом.

Используя библиотеку paramiko - чистую реализацию python SSH2-ваш скрипт python может подключиться к удаленному хосту через SSH, скопировать себя (!) к этому хосту, а затем выполнить эту копию на удаленном хосте. Stdin, stdout и stderr удаленного процесса будут доступны в локальном запущенном скрипте. Таким образом, это решение в значительной степени не зависит от ИНТЕГРИРОВАННАЯ СРЕДА РАЗРАБОТКИ.

На моем локальном компьютере я запускаю сценарий с параметром командной строки deploy, который запускает удаленное выполнение. Без такого параметра выполняется фактический код, предназначенный для удаленного хоста.

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

Обработка исключений опущена, чтобы упростить этот пример. В проектах с несколькими файлами сценариев вам, вероятно, придется поместить все эти файлы (и другие зависимости) на удаленный хост.

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

Потому что cat | обычно не требуется

Вы можете сделать это через ssh.

ssh user@192.168.1.101 "python ./hello.py"

Вы также можете редактировать скрипт в ssh с помощью текстового редактора или переадресации X11.

Мне пришлось сделать это перед использованием Paramiko в случае, когда я хотел запустить динамический, локальный скрипт PyQt4 на хосте, работающем на ssh-сервере, который подключил Мой OpenVPN-сервер и запросил их предпочтения маршрутизации (сплит-туннелирование).

Пока ssh-сервер, к которому вы подключаетесь, имеет все необходимые зависимости вашего скрипта (PyQt4 в моем случае), вы можете легко инкапсулировать данные, кодируя их в base64 и используя встроенную функцию exec() для декодированного сообщения. Если я помните правильно мой однострочный для этого был:
stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]

Это трудно читать, и вы должны избежать escape-последовательностей, потому что они интерпретируются дважды (один раз отправителем, а затем снова получателем). Он также может нуждаться в некоторой отладке, я упаковал свой сервер на ПК или я бы просто сослался на свой сценарий маршрутизации OpenVPN.

Разница в этом способе, в отличие от отправки файла, заключается в том, что он никогда не касается диска на сервере и запускается прямо из памяти (если только конечно, они регистрируют команду). Вы обнаружите, что инкапсуляция информации таким способом (хотя и неэффективным) может помочь вам упаковать данные в один файл.

Например, этот метод можно использовать для включения необработанных данных из внешних зависимостей(например, изображения) в основной сценарий.