2025, Nov 15 09:04
Как запустить Python из PowerShell так, чтобы он пережил закрытие терминала
Как запустить Python‑скрипт в фоне из PowerShell и пережить закрытие Windows Terminal: используем conhost.exe и Start‑Process с параметром -WindowStyle Hidden.
Запустить Python‑задачу из PowerShell так, чтобы она продолжала работать после закрытия терминала, кажется пустяком — пока не попробуешь и не увидишь, как процесс исчезает вместе с окном. В bash проблему решают nohup и амперсанд. В PowerShell эквивалент есть, но путь иной — особенно на системах, где Windows Terminal выбран консолью по умолчанию.
Постановка задачи
В Linux длительный скрипт, который должен пережить терминал, обычно запускают так:
nohup python app_main.py &
Попытка повторить идею в PowerShell прямым запуском не срабатывает: процесс остаётся привязан к текущей консольной сессии:
python app_main.py
Даже передача запуска дочернему процессу не спасает, если потомок всё равно связан с тем же жизненным циклом терминала:
Start-Process python app_main.py
Почему это не работает в PowerShell
Суть в привязке процесса к хосту терминала. В современных установках Windows приложением консоли по умолчанию часто является Windows Terminal. Запуск нового процесса из PowerShell без дополнительного посредника обычно открывает его в новой вкладке Windows Terminal, которая остаётся дочерней по отношению к самому терминалу. Закрываете Windows Terminal — и дочерний процесс завершается вместе с ним. Не хватает независимого консольного хоста, который бы отвязал дерево процессов от жизненного цикла терминала.
Эквивалент «nohup … &» в Windows
Используйте Start-Process через conhost.exe. Этот консольный хост создаёт для процесса независимую консольную сессию. Чтобы не показывать окно, управляйте его видимостью с помощью -WindowStyle. Режим Hidden позволяет отправить задачу в фон и гарантирует, что процесс продолжит работу после закрытия терминала:
Start-Process -WindowStyle Hidden conhost.exe 'python app_main.py'
Не добавляйте -NoNewWindow — этот параметр снова привяжет Python‑процесс к текущей консоли и сведёт на нет попытку пережить закрытие терминала. Запуск через conhost.exe — принципиальный момент: без него процесс может оказаться во вкладке Windows Terminal и по-прежнему завершится вместе с терминалом.
Есть и важные ограничения. Этот приём не подходит для сеансов удалённого PowerShell (remoting): запущенный процесс в таком контексте будет вести себя не так, как вы ожидаете. Кроме того, в Unix‑подобных системах Start-Process не создаёт независимых окон терминала, поэтому там по‑прежнему нужен nohup.
Рабочий пример фонового запуска
Чтобы запустить скрипт Python полностью отвязанным от текущей сессии PowerShell и без видимого окна, выполните:
Start-Process -WindowStyle Hidden conhost.exe 'python app_main.py'
Команда запускает интерпретатор в отдельном консольном хосте. Если ваш код на Python порождает подпроцессы, они унаследуют ту же независимость от исходного терминала, поэтому закрытие PowerShell или Windows Terminal их не остановит.
Почему это важно
Интерактивные оболочки — ненадёжные «супервизоры» для долгих задач. Когда приложению терминала принадлежит контроль над сроком жизни вашего дерева процессов, обычные действия вроде закрытия окна могут прервать работу, повредить промежуточные данные или оставить частичные результаты. Отвязав задачу от терминала, вы избегаете этих рисков и обеспечиваете Python‑процессу и его потомкам стабильную среду выполнения.
Вывод
Если вам нужен Windows‑эквивалент nohup … & для запуска Python из PowerShell, делегируйте запуск conhost.exe и скрывайте окно с помощью -WindowStyle Hidden. Не используйте -NoNewWindow, чтобы процесс не остался привязан к текущей консоли. Помните: этот подход не для сценариев remoting, а в Unix‑подобных системах по‑прежнему нужен nohup. С такой конфигурацией фоновые задачи работают устойчиво и не прекращаются при закрытии терминала.