Как запустить серверный скрипт на неопределенный срок - PullRequest
2 голосов
/ 18 декабря 2009

Я бы хотел бесконечно запускать асинхронную программу на удаленном сервере Linux. Этот скрипт ничего не выводит на сам сервер (кроме периодической записи информации в базу данных mysql). Пока единственная опция, которую мне удалось найти, - это команда nohup:

nohup script_name &

Насколько я понимаю, nohup позволяет запускать команду даже после того, как я выйду из сеанса SSH, а символ '&' позволяет запускать команду в фоновом режиме. Мой вопрос прост: это лучший способ сделать то, что я хотел бы? Я только пытаюсь запустить один сценарий в течение длительного времени, время от времени останавливая его для обновления.

Кроме того, если nohup действительно лучший вариант, как правильно завершить сценарий, когда мне нужно? Кажется, есть некоторые разногласия по поводу того, что является лучшим способом убить процесс nohup.

Спасибо

Ответы [ 4 ]

3 голосов
/ 18 декабря 2009

То, что вы в основном спрашиваете: «Как мне создать процесс демона?» То, что вы хотите сделать, это «демонизировать», есть много примеров этого в Интернете. Процесс в основном таков: fork(), дочерний процесс создает новый сеанс, родительский процесс завершается, дочерний процесс дублирует, а затем закрывает открытые дескрипторы файлов на управляющем терминале (STDIN, STDOUT, STDERR).

Доступен пакет, который сделает все это за вас python-daemon .

Чтобы выполнить корректное завершение работы, посмотрите библиотеку сигналов для создания обработчика сигналов.

Кроме того, поиск в сети «демона python» вызовет много повторных реализаций общего процесса демонизации C: http://code.activestate.com/recipes/66012/

2 голосов
/ 18 декабря 2009

Если вы можете изменить скрипт, то вы можете поймать SIGHUP сигналы и избежать необходимости nohup. В скрипте bash вы бы написали:

trap " echo ignoring hup; " SIGHUP

Вы можете использовать ту же технику для завершения программы: перехватить, скажем, сигнал SIGUSR1 в обработчике, установить флаг и затем корректно выйти из основного цикла. Таким образом, вы можете послать этот сигнал по вашему выбору, чтобы остановить вашу программу предсказуемым образом.

1 голос
/ 17 февраля 2010

Бывают ситуации, когда вы хотите выполнить / запустить некоторые сценарии на удаленном компьютере / сервере (которые завершатся автоматически) и отключиться от сервера.

Например: скрипт, запущенный на блоке, который при выполнении 1) берет модель и копирует ее на кастер (удаленный сервер) 2) создает скрипт для запуска симуляции с помощью wodel и передает его на сервер 3) запускает Сценарий на сервере и отключение. 4) Запущенный сценарий должен запустить симуляцию на сервере и после ее завершения (потребуется несколько дней) скопировать результаты обратно клиенту.

Я бы использовал следующую команду:

ssh remoteserver 'nohup /path/to/script `</dev/null` >nohup.out 2>&1 &'

например:

echo '#!/bin/bash  
rm -rf statuslist  
mkdir statuslist  
chmod u+x ~/monitor/concat.sh  
chmod u+x ~/monitor/script.sh  
nohup ./monitor/concat.sh &  
' > script.sh 

chmod u+x script.sh

rsync -azvp script.sh remotehost:/tmp

ssh remoteshot '/tmp/script.sh `</dev/null` >nohup.out 2>&1 &'

Надеюсь, это поможет; -)

0 голосов
/ 18 декабря 2009

Это самый простой способ сделать это, если вы хотите (или должны) избежать изменения самого скрипта. Если скрипт всегда должен выполняться так, вы можете написать мини-скрипт, содержащий только что введенную строку, и запустить ее вместо этого. (или используйте псевдоним, если необходимо)

Чтобы ответить на второй вопрос:

 $ nohup ./test &
[3] 11789
 $ Sending output to nohup.out

$jobs
[1]-  Running                 emacs *h &
[3]+  Running                 nohup ./test &
$ kill %3
$ jobs
[1]-  Running                 emacs *h &
[3]+  Exit 143                nohup ./test

Ctrl + c тоже работает (отправляет SIGINT), как и kill (отправляет SIGTERM)

...