2013-12-10 1 views
19

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

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

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

ответ

37

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

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

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

+0

Разве вы не можете оставить «-'? Это нормально для меня. –

+1

Что делать, если код имеет подмодули, расположенные в подпапках? –

+2

Где вы могли бы добавить аргументы командной строки в этом случае? – ubundows

3

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

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

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

+4

Это выполняет сценарий _remote_ питона на удаленном сервере. Насколько я понимаю, автор хочет выполнить скрипт _local_ python на удаленном сервере. – Sney

+0

Да, вы правы. Я предлагал делать изменения через ssh тоже, прямо на удаленной машине, чтобы избежать «стадии загрузки». Фактически вы можете загрузить и выполнить файл в одной строке (например, http://unix.stackexchange.com/a/57809). Но это решение выглядит немного грязным для меня ... – smeso

25

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

Использование библиотеки paramiko - чистая реализация python SSH2 - ваш скрипт python может подключаться к удаленному хосту через SSH, копировать себя (!) На этот хост, а затем выполнять эту копию на удаленном хосте. Stdin, stdout и stderr удаленного процесса будут доступны на вашем локальном скрипте. Таким образом, это решение практически не зависит от IDE.

На моей локальной машине запускаю скрипт с параметром cmd-line «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() 

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

+0

Могу ли я использовать эту конструкцию также как 'с открытым paramiko.SSHClien() ... ', чтобы не забыть закрыть()? – Mrlenny

+0

Убедитесь, что len (sys.argv)> 1, в противном случае скрипт сработает на пульте дистанционного управления. Кроме того, ваша bashrc (или начальная конфигурация оболочки) на пульте дистанционного управления не должна содержать отпечатков на stdout (эхо в bash). –

0

Мне пришлось сделать это до использования 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] 

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^