Запустите программу из python и продолжайте ее запускать после того, как script будет убит
Я пробовал использовать такие вещи:
subprocess.Popen(['nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'))
Это работает, если родительский script выходит изящно, но если я убью script (Ctrl-C), все мои дочерние процессы также будут убиты. Есть ли способ избежать этого?
Платформами, которые меня волнуют, являются OS X и Linux, используя Python 2.6 и Python 2.7.
Ответы
Ответ 1
Обычный способ сделать это в системах Unix - это разветкиться и выйти, если вы родитель. Посмотрите на os.fork()
.
Вот функция, которая делает эту работу:
def spawnDaemon(func):
# do the UNIX double-fork magic, see Stevens' "Advanced
# Programming in the UNIX Environment" for details (ISBN 0201563177)
try:
pid = os.fork()
if pid > 0:
# parent process, return and keep running
return
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
os.setsid()
# do second fork
try:
pid = os.fork()
if pid > 0:
# exit from second parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
sys.exit(1)
# do stuff
func()
# all done
os._exit(os.EX_OK)
Ответ 2
Детский процесс получает тот же SIGINT, что и ваш родительский процесс, потому что он находится в той же группе процессов. Вы можете поместить ребенка в свою собственную группу процессов, вызвав os.setpgrp() в дочернем процессе. Аргумент Popen preexec_fn полезен здесь:
subprocess.Popen(['nohup', 'my_command'],
stdout=open('/dev/null', 'w'),
stderr=open('logfile.log', 'a'),
preexec_fn=os.setpgrp
)
(preexec_fn используется только для un * x-oids. Судя по всему, для Windows создается "эквивалент" createflags = CREATE_NEW_PROCESS_GROUP, но я никогда не пробовал.)
Ответ 3
Запустите подпроцесс .Popen() в отдельном потоке.