
Я обычно использую подсистему Linux, когда программирую что-либо в Windows 10, поэтому все мои пути являются относительными к ~
. У меня есть скрипт Python, который работает вечно в фоновом режиме, пока я не убью процесс. Как бы я сделал это в Windows 10 Bash без открытого терминала?
Что я пробовал:
bash -c "python3 script.py
из Бега.nohup python3 -u script.py
затем закройте терминал.setsid python3 script.py
затем закройте терминал.
Ничего из этого не сработало. Есть ли способ сделать это? Или есть ли способ изменить пути так, чтобы они работали, если я запускаю скрипт из W10 И bash, не переключая их каждый раз?
решение1
Недавнее дополнение к 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" &
Примечание: в настоящее время я использую win10_64, версия 1709 (сборка ОС 16299.64).
решение2
Обновлять
Microsoft устранила эту проблему. Фоновые процессы/процессы демонов теперь могут продолжать работать даже после bash.exe
закрытия (или другого процесса запуска WSL). Требуется последняя сборка Win10 (весна 2018 года для публичных релизов, сборка 17046 или выше).
Нижеследующее сохранено для потомков.
Печально/абсурдно, но нет способа сделать это. Microsoft, в своей бесконечной мудрости, решила, что WSL (подсистема Windows для Linux) будет работать только пока у вас bash.exe
открыт процесс. Закройте последний (или, возможно, даже закройте последнийокно; Я не уверен, выдержит ли он работу в автономном режиме) и WSL завершает работу, убивая все свои процессы.
Оправданием этого было «сбережение ресурсов», что абсурдно на нескольких уровнях, но прежде всего потому, что, черт возьми, у моего компьютера есть эти ресурсы, и они существуют для того, чтобы их использовать! Если я хочу, чтобы процесс запускался, он должен запускаться; если я не хочу, чтобы он запускался, я могу его убить. Для чего-то явно предназначенного как инструмент разработчика, иногда кажется, что WSL можно использовать только как игрушку, и нельзя доверять его пользователям, чтобы они знали, что они делают.
В любом случае, если вы хотите это исправить, голосуйте заРассмотрите возможность включения заданий cron, демонов и фоновых задач.настраница UserVoice. В настоящее время это второй по количеству голосов запрос, и он находится «в очереди».
решение3
Да, на данный момент это «невозможно».
Но возможно заставить его "выглядеть" как фоновый процесс с помощью некоторых трюков. Я сам очень хотел эту функциональность, поэтому через пару часов я придумал дерьмовое, но работающее решение.
Главное — создать невидимую оболочку, в которой вы запускаете WSL Bash с помощью VBScript. Затем вы можете запустить этот скрипт при запуске. Правильное планирование задач не сработало по какой-то странной причине.
На стороне Linux для включения демонов вы можете иметь собственную элементарную систему запуска, которая, например, использует .bashrc.
Процесс подробно описан в этом документе, который я написал.https://emil.fi/bashwinЯ не реализовал мониторинг задач, но его должно быть довольно легко расширить.
решение4
Мне потребовалась целая вечность, но я нашел невероятно сложный способ сделать это (из пакетного файла):
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
необходимо устанавливать по-разному для каждого приложения. Возможно, вам даже придется его пропустить.