Запуск фонового процесса bash в Windows 10 без открытого терминала

13

Я обычно использую подсистему Linux, когда я что-то программирую на Windows 10, поэтому все мои пути относительно ~. У меня есть сценарий Python, который работает вечно в фоновом режиме, пока я не убью процесс. Как бы я сделал это на Windows 10 Bash без открытого терминала?

Вещи, которые я пробовал:

  • bash -c "python3 script.py от бега.
  • nohup python3 -u script.py затем закрытие терминала.
  • setsid python3 script.py затем закрытие терминала.

Ничего из этого не сработало. Есть ли способ сделать это? В качестве альтернативы, есть ли способ изменить пути, чтобы они работали, если я запускаю скрипт из W10 AND bash без необходимости каждый раз переключать их?

ясень
источник

Ответы:

7

Недавнее добавление к WSL позволяет запускать команды wsl непосредственно из меню «Выполнить» или «Пуск». Вы можете добавить к команде амперсанд (нормальное поведение оболочки), что приводит к мгновенному bashвыводу терминала, который немедленно исчезает, но команда продолжается.

Примеры, в Пуск »Выполнить :

wsl sleep 20 &
wsl python -c 'import time; time.sleep(20);' &

Если вы зайдете в диспетчер задач Windows, он покажет команду Sleepили, Python2работающую в течение 20 секунд, а затем самоочищение.

Я обнаружил, что переменные окружения недоступны. Например, DISPLAYесли установить в окна обычным способом, не передается WSL. Для этого должен быть способ передачи этих переменных. Даже если команда не поддерживает установку необходимой переменной с помощью аргумента командной строки, это можно сделать с помощью bashсамого себя:

# direct, command-dependent
wsl emacs --display=:0 &

# indirect, more flexible
wsl bash -c "DISPLAY=:0 emacs" &

NB: я сейчас использую win10_64, версию 1709 (сборка ОС 16299.64).

r2evans
источник
13

Обновить

Microsoft обратилась к этому. Фоновые / демонические процессы теперь могут продолжать работать даже после bash.exeзакрытия (или другого процесса запуска WSL). Требуется последняя сборка Win10 (весна 2018 г. для публичных выпусков, сборка 17046 или выше).

Ниже сохраняется для потомков.


К сожалению / нелепо, нет способа сделать это. Microsoft в своей бесконечной мудрости решила, что WSL (Windows Subsystem for Linux) будет работать только тогда, когда у вас открыт bash.exeпроцесс. Закройте последнее (или, возможно, даже закройте последнее окно ; я не уверен, что оно допустит запуск без заголовка), и WSL завершает работу, убивая все его процессы.

Основанием для этого было «сохранить ресурсы», что абсурдно на нескольких разных уровнях, но прежде всего потому, что, черт возьми, у моего компьютера есть эти ресурсы, и они там для использования! Если я хочу, чтобы процесс выполнялся, он должен запускаться; если я не хочу, чтобы он работал, я могу убить его. Для чего-то, явно предназначенного для инструмента разработчика, иногда кажется, что WSL можно использовать только как игрушку, и его пользователям нельзя доверять, чтобы знать, что они делают.

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

CBHacking
источник
«В первую очередь потому, что, черт возьми, у моего компьютера есть эти ресурсы, и они там должны быть использованы», очень хорошо сказано! это действительно поражает воображение ...
авиаудар
У меня есть сборка 17134, и у меня не может быть фоновой работы без окна bash.
Джон Пик
@JohnPick Они не будут запускаться автоматически после перезагрузки, но они должны продолжать работать, когда окно закрыто (если, конечно, они не прикреплены к нему).
CBHacking
@CBHacking Чтобы быть более точным, если я запускаю сервер Node.js в фоновом режиме, то это одновременно и job ( jobs), и process ( ps aux). Я могу использовать, fgчтобы вывести его на передний план. Но после того, как я закрыл последнее окно bash и открыл новое окно bash, задание пропало, процесс все еще выполняется, и я не могу переместить процесс на передний план. Извините, если моя терминология выключена.
Джон Пик
@JohnPick Ах, это совершенно другая проблема - этот вопрос касается процессов, а не управления заданиями оболочки - и его следовало бы задать в другом месте, но ответ достаточно прост, я дам его здесь: запустить процесс в разделе tmuxили screenдля поддержки повторное подключение к другому терминалу. Linux (и другие * nix) машины, работающие в натуре, имеют то же ограничение.
CBHacking
2

Да, это "невозможно" в данный момент.

Но можно сделать так, чтобы он «выглядел» как фоновый процесс с некоторыми хитростями. Я сам очень хотел эту функциональность, поэтому через пару часов я нашел дерьмовое, но работающее решение.

Суть в том, чтобы создать невидимую оболочку, для которой вы запускаете WSL Bash с VBScript. Затем вы можете запустить этот скрипт при запуске. Правильное планирование задач не сработало по какой-то странной причине.

На стороне Linux для включения демонов у вас может быть собственная элементарная система запуска, которая, например, использует .bashrc.

Процесс подробно описан здесь, в этом документе я написал https://emil.fi/bashwin . Я не реализовывал мониторинг задач, но его было довольно просто расширить.

Эмиль
источник
2

Вы пробовали это решение?

Он использует помощник WSH для запуска любого скрытого приложения.

Затем вы можете просто создать новую задачу в Tak Scheduler, чтобы запустить команду при входе в систему. Что-то вродеwscript <path to runHidden.vbs> bash.exe -c "python script.py"

Магнус
источник
2

Это заняло у меня навсегда, но я нашел глупо сложный способ сделать это (из командного файла):

start bash -c "DISPLAY=:0 [command] & (sleep 0.5 && kill -n 9 $$)"

Вот разбивка того, что он делает и почему:

  • `start`: чтобы закрыть окно командного файла
  • `bash -c`: позволяет запустить команду bash
  • `DISPLAY =: 0`: устанавливает ваш X-сервер
  • `[команда]`: ваша команда / команды (`[команда && [команда]`)
  • `&`: заставить следующую команду выполняться после ее запуска, а не когда она будет выполнена
  • `sleep 0.5`: чтобы убедиться, что процесс запущен
  • `&&`: запускать следующую команду после выполнения, а не при запуске
  • `kill -n 9 $$`: убить оболочку bash, чтобы это было только графическое приложение

Примечание: DISPLAY=:0устанавливает его для x-сервера в :0. Чтобы изменить его (например) :1, сделать DISPLAY=:1и т. Д.

Примечание: startтребуется только если это из пакетного скрипта. Если это из терминала, вам это не нужно

Примечание: sleepнеобходимо установить по-разному для каждого приложения. Возможно, вам даже придется пропустить это.

Electroboss
источник
0

Я не знаю, насколько хорошо Windows Service Manager (SrvMan) из http://tools.sysprogs.org/srvman/ будет работать для вас, но он работал для меня для других программ. На самом деле, я попытался запустить bash.exe в качестве службы, чтобы посмотреть, будет ли он работать, и я предполагаю, что мне придется немного повозиться, чтобы LAMP действительно работал в фоновом режиме.

Чарльз Макдональд
источник
1
Как это решает вопрос о том, как запустить скрипт Python в фоновом режиме?
Скотт