удаленно запустить программу Python в фоновом режиме

Мне нужно использовать fabfile, чтобы время от времени удаленно запускать какую-то программу в удаленных ящиках и получать результаты. Поскольку выполнение программы занимает много времени, я хочу, чтобы она работала в фоновом режиме, поэтому мне не нужно ждать. Поэтому я попробовал os.fork(), чтобы заставить его работать. Проблема в том, что когда я подключаюсь по ssh к удаленному ящику и запускаю там программу с помощью os.fork(), программа может нормально работать в фоновом режиме, но когда я попытался использовать запуск fabfile, sudo для удаленного запуска программы, os. fork() не может работать, программа просто молча умирает. Поэтому я переключился на Python-daemon, чтобы демонизировать программу. Какое-то время все работало отлично. Но теперь, когда я начал заставлять свою программу читать некоторые полки Python, python-daemon больше не может работать. Похоже, если вы используете python-daemon, полочные словари не могут быть загружены правильно, и я не знаю, почему. У кого-нибудь есть идея, кроме os.fork() и Python-daemon, что еще я могу попробовать решить мою проблему?


person Sheng    schedule 05.06.2011    source источник
comment
cron job?, вроде так   -  person Jakob Bowyer    schedule 05.06.2011
comment
Как насчет использования команды оболочки nohup для запуска в фоновом режиме при входе через SSH?   -  person Sven Marnach    schedule 05.06.2011


Ответы (2)


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

Скажем ради обсуждения, что вы хотели запустить program.sh и собрать то, что он отправляет на стандартный вывод. Чтобы сделать это с тканью, создайте локально:

Фабфайл.py:

from fabric.api import run
def runmyprogram():
    run('./program.sh > output 2> /dev/null < /dev/null &')

Затем локально запустите:

fab -H remotebox runmyprogram

Программа будет выполняться удаленно, но ткань не будет ждать ее завершения. Вам нужно будет собрать выходные файлы позже, возможно, используя scp. Знак «&» запускает это в фоновом режиме на удаленной машине, а перенаправление вывода необходимо на предотвращает зависание сеанса Fabric.

Если вам не нужно использовать ткань, есть более простые способы сделать это. Вы можете ssh индивидуально и запустить

nohup ./program.sh > output &

затем вернитесь позже, чтобы проверить вывод.

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

Если вы не хотите собирать выходные файлы позже, вы можете использовать:

Фабфайл.py:

from fabric.api import run
def runmyprogram():
    run('./program.sh')

Затем на вашей локальной машине:

fab -H remotebox runmyprogram > output &

Задания будут выполняться удаленно и помещать все свои выходные данные обратно в локальный выходной файл. Это работает в фоновом режиме на вашем локальном компьютере, поэтому вы можете заниматься другими делами. Однако, если соединение между вашей локальной и удаленной машинами может быть прервано, лучше использовать первый подход, чтобы выходные данные всегда безопасно сохранялись на удаленных машинах.

person Chris P    schedule 05.06.2011
comment
Привет, Крис. Я думаю, когда программа все еще работает в удаленном ящике, и если затем убить fab, программа умрет немедленно. Что бы вы сделали особенного, чтобы этого не произошло? просто добавить & в конце потрясающей команды? Большое спасибо за вашу помощь! - person Sheng; 06.06.2011
comment
Шэн, удаленная программа будет продолжать работать, даже если fab будет уничтожен локально (по крайней мере, в моих тестах; я не могу найти документацию, подтверждающую это). Тем не менее, я обновил свой ответ, чтобы предоставить лучший метод, если вы предпочитаете просто запускать работу удаленно в фоновом режиме и позволять ткани немедленно завершиться локально. - person Chris P; 07.06.2011
comment
Крис, теперь, когда я снова могу заставить Python-daemon работать, я бы просто придерживался старого пути. Но ваше решение может быть элегантным, если оно работает для моей проблемы, я все равно попробую его во время обеденного перерыва tmr. Большое спасибо за ваши обновления! - person Sheng; 07.06.2011

Для тех, кто наткнулся на этот пост в будущем. Python-демон все еще может работать. Просто обязательно загрузите слова полки в том же процессе. Таким образом, ранее полочные диктанты загружались в родительский процесс, когда python-daemon порождает дочерний процесс, обработчик dict передается неправильно. Когда мы исправим это, все снова работает.

Спасибо тем, кто предлагает ценные комментарии в этой теме!

person Sheng    schedule 06.06.2011