Запуск фонового процесу 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якщо встановлено у звичайному методі Windows, не передається WSL. Для цього потрібен спосіб передачі цих змінних. Навіть якщо команда не підтримує встановлення потрібної змінної за допомогою аргументу командного рядка, це можна зробити за допомогою bashсамої:

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

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

NB: На даний момент я працюю win10_64, версія 1709 (збірка ОС 16299.64).


13

Оновлення

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

Нижче збережено для нащадків.


Сумно / безглуздо, немає ніякого способу зробити це. Майкрософт у своїй безмежній мудрості вирішив, що WSL (підсистема Windows для Linux) буде працювати лише тоді, коли ви bash.exeвідкриєте процес. Закрийте останнє (або, можливо, навіть закрийте останнє вікно ; я не впевнений, чи буде він терпіти запуск без голови), і WSL вимикається, вбиваючи всі його процеси.

Виправданням цього було "збереження ресурсів", що абсурдно на декількох різних рівнях, але найголовніше тому, що, чорт забирай, мій комп'ютер має ці ресурси, і вони є там, щоб їх використовувати! Якщо я хочу запустити процес, він повинен запуститися; якщо я не хочу, щоб він запускався, я можу його вбити. Щось явно призначене як інструмент для розробників, іноді здається, що WSL є корисним лише як іграшка, і його користувачам не можна довіряти, що вони роблять.

У будь-якому разі, якщо ви хочете, щоб це було виправлено, проголосуйте за розгляд питання про ввімкнення завдань на роботу з крон, демонів та фонових завдань на сторінці UserVoice . Наразі це другий за рейтингом запит і "знаходиться на відсталі".


"Найголовніше тому, що, чорт забирай, мій комп'ютер має ці ресурси, і їх там можна використовувати" дуже добре! це справді кидає розум ...
авіанапад

У мене є збірка 17134 і не може бути фонове завдання без вікна bash.
Джон Пік

@JohnPick Вони не запускаються автоматично після перезавантаження, але вони повинні працювати, коли вікно закрите (доки, звичайно, вони не прикріплені до нього).
CBHacking

@CBHacking Щоб бути більш конкретним, якщо я запускаю сервер Node.js у фоновому режимі, то це і робота ( jobs), і процес ( 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-сервер
  • `[команда]`: ваша команда / команди (`[команда && [команда]`)
  • `&`: Щоб зробити таку команду бігти після того, як він починає і не тоді , коли це зроблено
  • `сон 0,5 ': щоб переконатися, що процес почався
  • `` &&: зробити наступну команду бігти після того, як це робиться , і не тоді , коли він починає
  • `kill -n 9 $$`: вбивати оболонку bash, тому це лише графічний додаток

Примітка: DISPLAY=:0встановлює його на x-сервер на :0. Щоб змінити його на (наприклад) :1, зробіть DISPLAY=:1і т.д.

Примітка. startПотрібна лише в тому випадку, якщо це з пакетного сценарію. Якщо це з терміналу, вам це не потрібно

Примітка: sleepдля кожної програми потрібно встановити по-різному. Можливо, вам навіть доведеться пропустити це.


0

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


1
Як це вирішує питання про те, як запустити сценарій Python у фоновому режимі?
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.