Мне нужно запустить команду оболочки асинхронно из сценария Python. Под этим я подразумеваю, что я хочу, чтобы мой скрипт Python продолжал работать, пока внешняя команда отключается и делает все, что ей нужно.
Я прочитал этот пост:
Затем я ушел и провел некоторое тестирование, и, похоже, os.system()
он выполнит работу при условии, что я использую &
в конце команды, чтобы мне не пришлось ждать ее возврата. Меня интересует, правильно ли это сделать? Я пробовал, commands.call()
но у меня это не сработает, потому что блокируется внешняя команда.
Пожалуйста, дайте мне знать, os.system()
рекомендуется ли использовать для этого или я должен попробовать другой путь.
источник
Если вы хотите запускать несколько процессов параллельно, а затем обрабатывать их, когда они дают результаты, вы можете использовать опрос, как показано ниже:
Поток управления там немного запутан, потому что я стараюсь сделать его небольшим - вы можете рефакторинг по своему вкусу. :-)
Это дает преимущество в том, что в первую очередь обслуживаются запросы раннего завершения. Если вы вызываете
communicate
первый запущенный процесс, и он работает дольше всех, другие запущенные процессы будут бездействовать, тогда как вы могли бы обрабатывать их результаты.источник
os.waitpid
напрямую, что позволяет проверить, изменил ли какой-либо дочерний процесс свой статус.['/usr/bin/my_cmd', '-i', path]
вместо['/usr/bin/my_cmd', '-i %s' % path]
Мне интересно, является ли эта [os.system ()] правильным способом для выполнения такой задачи?
Нет,
os.system()
это не правильный путь. Вот почему все говорят использоватьsubprocess
.Для получения дополнительной информации прочтите http://docs.python.org/library/os.html#os.system.
источник
У меня был хороший успех с модулем asyncproc , который хорошо справляется с выводом процессов. Например:
источник
Другой способ сделать это - использовать pexpect с неблокирующими строками чтения . Pexpect решает проблемы взаимоблокировки, позволяет легко запускать процессы в фоновом режиме и дает простые способы иметь обратные вызовы, когда ваш процесс выплевывает предопределенные строки, и в целом значительно упрощает взаимодействие с процессом.
источник
Учитывая «мне не нужно ждать, пока он вернется», одним из самых простых решений будет следующее:
Но ... Из того, что я прочитал, это не «правильный способ сделать это» из-за рисков безопасности, создаваемых
subprocess.CREATE_NEW_CONSOLE
флагом.Ключевые вещи, которые здесь происходят, - это использование
subprocess.CREATE_NEW_CONSOLE
для создания новой консоли и.pid
(возвращает идентификатор процесса, чтобы вы могли позже проверить программу, если хотите), чтобы не ждать, пока программа завершит свою работу.источник
У меня такая же проблема при попытке подключиться к терминалу 3270 с помощью программного обеспечения сценариев s3270 на Python. Теперь я решаю проблему с подклассом Process, который нашел здесь:
http://code.activestate.com/recipes/440554/
А вот образец из файла:
источник
Принятый ответ очень старый.
Я нашел здесь лучший современный ответ:
https://kevinmccarthy.org/2016/07/25/streaming-subprocess-stdin-and-stdout-with-asyncio-in-python/
и внес некоторые изменения:
Маловероятно, что приведенные в примере команды будут идеально работать в вашей системе и не будут обрабатывать странные ошибки, но этот код действительно демонстрирует один из способов запуска нескольких подпроцессов с использованием asyncio и потоковой передачи вывода.
источник
wait()
напрямую устарелаЗдесь есть несколько ответов, но ни один из них не удовлетворяет моим нижеприведенным требованиям:
Я не хочу ждать завершения команды или засорять мой терминал выводами подпроцесса.
Я хочу запустить сценарий bash с перенаправлением.
Я хочу поддерживать конвейер в моем сценарии bash (например
find ... | tar ...
).Единственная комбинация, которая удовлетворяет вышеуказанным требованиям:
источник
Это рассматривается в примерах подпроцесса Python 3 в разделе «Подождите, пока команда не завершится асинхронно»:
Процесс начнется, как только
await asyncio.create_subprocess_exec(...)
будет завершен. Если к тому времени, когда вы позвонитеawait proc.communicate()
, он не будет завершен , он будет ждать там, чтобы сообщить вам статус вашего вывода. Если он закончился,proc.communicate()
немедленно вернусь.Суть здесь аналогична ответу Террелса но я думаю, что ответ Террелса, похоже, слишком усложняет ситуацию.
См.
asyncio.create_subprocess_exec
Дополнительную информацию.источник