Ausführen eines Bash-Hintergrundprozesses unter Windows 10 ohne offenes Terminal

13

Normalerweise verwende ich das Linux-Subsystem, wenn ich etwas unter Windows 10 programmiere, sodass alle meine Pfade relativ zu sind ~. Ich habe ein Python-Skript, das für immer im Hintergrund ausgeführt wird, bis ich den Prozess beende. Wie würde ich das unter Windows 10 ohne offenes Terminal machen?

Dinge, die ich versucht habe:

  • bash -c "python3 script.py von Run.
  • nohup python3 -u script.py dann das Terminal schließen.
  • setsid python3 script.py dann das Terminal schließen.

Nichts davon hat funktioniert. Gibt es eine Möglichkeit, dies zu tun? Gibt es alternativ eine Möglichkeit, die Pfade so zu ändern, dass sie funktionieren, wenn ich das Skript von W10 AND Bash aus starte, ohne sie jedes Mal wechseln zu müssen?

Asche
quelle

Antworten:

7

Eine kürzlich erfolgte Erweiterung der WSL ermöglicht das Starten von WSL-Befehlen direkt über das Menü "Ausführen" oder "Start". Sie können eine kaufmännische auf den Befehl (normale Shell - Verhalten) anhänge, die in einem momentanen Ergebnis bashEndgerät , das sofort verschwindet , aber der Befehl wird fortgesetzt.

Beispiele unter Start »Ausführen :

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

Wenn Sie in Windows-Task - Manager gehen, wird es eine Show Sleepoder Python2Befehl für 20 Sekunden ausgeführt wird , dann selbstlöschend.

Eine Sache, die ich gefunden habe, ist, dass Umgebungsvariablen nicht verfügbar sind. Wenn dies beispielsweise DISPLAYin der normalen Windows-Methode festgelegt ist, wird es nicht an die WSL übergeben. Dazu muss es eine Möglichkeit geben, diese Variablen zu übergeben. Auch wenn der Befehl das Festlegen der erforderlichen Variablen über ein Befehlszeilenargument nicht unterstützt, können Sie dies mit sich bashselbst tun :

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

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

NB: Ich verwende derzeit win10_64, Version 1709 (OS Build 16299.64).

r2evans
quelle
13

Aktualisieren

Microsoft hat dies angesprochen. Hintergrund- / Dämonprozesse können jetzt auch nach dem bash.exeSchließen (oder eines anderen WSL-Startprozesses) weiter ausgeführt werden. Ein aktueller Build von Win10 (Frühjahr 2018 für öffentliche Versionen, Build 17046 oder höher) ist erforderlich.

Das Folgende ist für die Nachwelt erhalten.


Leider / absurd gibt es keine Möglichkeit, dies zu tun. Microsoft hat in seiner unendlichen Weisheit entschieden, dass WSL (Windows Subsystem für Linux) nur ausgeführt wird, wenn Sie einen bash.exeProzess geöffnet haben. Schließen Sie das letzte Fenster (oder schließen Sie möglicherweise sogar das letzte Fenster ; ich bin nicht sicher, ob es toleriert wird, ohne Kopf ausgeführt zu werden), und die WSL wird heruntergefahren, wodurch alle Prozesse beendet werden.

Die Rechtfertigung dafür war "Ressourcen zu schonen", was auf verschiedenen Ebenen absurd ist, aber vor allem, weil mein Computer verdammt noch mal über diese Ressourcen verfügt und sie zur Verwendung da sind! Wenn ein Prozess ausgeführt werden soll, sollte er ausgeführt werden. Wenn ich nicht will, dass es läuft, kann ich es töten. Für etwas, das ausdrücklich als Entwicklertool gedacht ist, scheint WSL manchmal nur als Spielzeug verwendbar zu sein, und seinen Benutzern kann nicht vertraut werden, dass sie wissen, was sie tun.

Wenn Sie dies beheben möchten, stimmen Sie auf der UserVoice-Seite für die Option zum Aktivieren von Cron-Jobs, Daemons und Hintergrundaufgaben ab . Es ist derzeit die am zweithäufigsten gewählte Anfrage und befindet sich "im Rückstand".

CBHacking
quelle
"Vor allem, weil mein Computer verdammt noch mal über diese Ressourcen verfügt und sie verwendet werden können", sehr gut ausgedrückt! es verwirrt wirklich den Verstand ...
Luftangriff
Ich habe Build 17134 und kann keinen Hintergrundjob ohne ein Bash-Fenster haben.
John Pick
@JohnPick Sie werden nach einem Neustart nicht automatisch gestartet, sollten aber weiterhin ausgeführt werden, wenn das Fenster geschlossen wird (solange sie natürlich nicht daran angeschlossen sind).
CBHacking
@CBHacking Um genauer zu sein, wenn ich einen Node.js-Server im Hintergrund starte, ist es sowohl ein Job ( jobs) als auch ein Prozess ( ps aux). Ich kann es verwenden fg, um es in den Vordergrund zu bringen. Aber nachdem ich das letzte Bash-Fenster geschlossen und ein neues Bash-Fenster geöffnet habe, ist der Job weg, der Prozess läuft noch und ich kann den Prozess nicht in den Vordergrund verschieben. Entschuldigung, wenn meine Terminologie nicht stimmt.
John Pick
@JohnPick Ah, das ist ein ganz anderes Problem - diese Frage bezieht sich auf Prozesse, nicht auf das Shell-Job-Management - und hätte an anderer Stelle gestellt werden müssen, aber die Antwort ist einfach genug. Ich gebe sie hier: Starten Sie den Prozess unter tmuxoder screenzur Unterstützung erneutes Anschließen an ein anderes Terminal. Linux-Computer (und andere * nix-Computer), die nativ ausgeführt werden, haben dieselbe Einschränkung.
CBHacking
2

Ja, es ist im Moment "unmöglich".

Aber es ist möglich, dass es wie ein Hintergrundprozess mit einigen Tricks "erscheint". Ich wollte diese Funktionalität selbst ziemlich schlecht, also fand ich nach ein paar Stunden eine beschissene, aber funktionierende Lösung.

Der Hauptpunkt besteht darin, eine unsichtbare Shell zu erstellen, zu der Sie WSL Bash mit VBScript starten. Sie können dieses Skript dann beim Start ausführen lassen. Die richtige Aufgabenplanung hat aus irgendeinem Grund nicht funktioniert.

Linux-Seite, um Daemons zu aktivieren, können Sie Ihr eigenes rudimentäres Startsystem haben, das zum Beispiel .bashrc missbraucht.

Der Prozess wird hier in diesem Dokument beschrieben, das ich unter https://emil.fi/bashwin geschrieben habe . Ich habe keine Aufgabenüberwachung implementiert, aber es sollte ziemlich einfach zu erweitern sein.

Emil
quelle
2

Haben Sie diese Lösung ausprobiert ?

Es verwendet einen WSH-Helfer, um versteckte Anwendungen zu starten.

Anschließend können Sie in Tak Scheduler einfach eine neue Aufgabe erstellen, um den Befehl beim Anmelden zu starten. Etwas wiewscript <path to runHidden.vbs> bash.exe -c "python script.py"

Magnus
quelle
2

Es hat ewig gedauert, aber ich habe einen dumm komplizierten Weg gefunden (aus einer Batch-Datei):

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

Hier ist eine Aufschlüsselung dessen, was es tut und warum:

  • `start`: damit das Batch-Datei-Fenster verschwindet
  • `bash -c`: Mit dieser Option können Sie einen Bash-Befehl ausführen
  • `DISPLAY =: 0`: Legt Ihren X-Server fest
  • `[Befehl]`: Ihr Befehl / Ihre Befehle (`[Befehl && [Befehl]`)
  • `&`: Auf das nächste Befehl zum Laufen zu bringen , nachdem es beginnt und nicht , wenn es getan
  • `sleep 0.5`: um sicherzustellen, dass der Prozess gestartet wurde
  • `` &&: auf das nächste Befehl zum Laufen zu bringen , nachdem es getan und nicht , wenn es beginnt
  • `kill -n 9 $$`: Um die Bash-Shell zu töten, ist dies nur die grafische Anwendung

Hinweis: DISPLAY=:0Setzt es auf den x-Server um :0. Um es in (zB) zu ändern :1, tun Sie DISPLAY=:1usw.

Hinweis: startist nur erforderlich, wenn es sich um ein Batch-Skript handelt. Wenn es vom Terminal kommt, brauchen Sie das nicht

Hinweis: sleepmuss für jede Anwendung anders eingestellt werden. Möglicherweise müssen Sie es sogar weglassen.

Electroboss
quelle
0

Ich weiß nicht, wie gut Windows Service Manager (SrvMan) von http://tools.sysprogs.org/srvman/ für Sie funktionieren würde, aber es hat für mich für andere Programme funktioniert. Tatsächlich habe ich versucht, die "bash.exe" als Dienst auszuführen, um zu sehen, ob sie funktionieren würde, und ich schätze, ich muss ein bisschen mehr basteln, damit LAMP tatsächlich im Hintergrund funktioniert.

Charles McDonald
quelle
1
Wie wird damit die Frage beantwortet, wie ein Python-Skript im Hintergrund ausgeführt werden soll?
Scott