подпроцесс.вызов nohup

#python #django #bash #scrapy #subprocess

#python #django #bash #scrapy #подпроцесс

Вопрос:

У меня есть функция (Django admin), которая запускает Scrapy spider. Функция работает правильно. Что я пытаюсь сделать сейчас, так это сделать его неблокирующим.

Это работает так, как ожидалось — мне нужно дождаться завершения SH-скрипта. Итак, в основном я нажимаю на это действие, и браузер ожидает окончания обхода.

 subprocess.call([settings.CRAWL_SH_ABS_PATH, "db_profiles_spider", "ids", ids])
  

Я хочу, чтобы он был неблокирующим, чтобы браузер немедленно обновлялся.

Я пробовал это:

 subprocess.call(["nohup",settings.CRAWL_SH_ABS_PATH, "db_profiles_spider", "ids", ids, 'amp;'])
  

Но, похоже, он блокируется, и браузер ожидает ответа. Почему? Как я могу заставить это работать?

Ответ №1:

amp; для оболочки, поэтому попробуйте так:

 cmd = ' '.join(["nohup", settings.CRAWL_SH_ABS_PATH, "db_profiles_spider",
                "ids", ids, 'amp;'])
subprocess.call(cmd, shell=True)
  

Обновить:

Для меня это также работает без использования nohup .

Вы также можете создать поток и запустить команду в этом потоке. Также можно os.fork() и запустить команду в дочернем процессе.

Комментарии:

1. просто попробовал и subprocess.call([...], shell=True) не работает. команда должна быть строкой.

2. Насколько я понимаю, nohup гарантирует, что выходные данные фонового процесса продолжают собираться, даже если родительский процесс больше не работает.

3. это имеет больше смысла, когда задействован pty, поэтому процесс будет защищен от SIGHUP.

4. например, согласно руководству по bash, «Оболочка завершается по умолчанию при получении SIGHUP. Перед завершением интерактивная оболочка повторно отправляет SIGHUP всем заданиям, запущенным или остановленным. Остановленные задания отправляются SIGCONT, чтобы убедиться, что они получают SIGHUP.» вы можете попробовать так: используйте putty для подключения по ssh к серверу (предположим, что удаленная оболочка — bash) и запустите sleep 9999 amp; , затем принудительно закройте окно putty. bash получит SIGHUP и отправит SIGHUP в процесс ожидания, и режим ожидания будет прерван.