it-swarm.com.de

Powershell-Äquivalent zu Bash-Et-Zeichen (&) zum Forken / Ausführen von Hintergrundprozessen

In Bash kann das kaufmännische Und (&) verwendet werden, um einen Befehl im Hintergrund auszuführen und die interaktive Steuerung an den Benutzer zurückzugeben, bevor der Befehl beendet ist. Gibt es eine äquivalente Methode, um dies in Powershell zu tun?

Anwendungsbeispiel in der Bash:

 sleep 30 &
134
eddiegroves

Das sind ein paar Antworten auf diese Frage.

  1. In Version 1 ist das nicht einfach
  2. Version 2 (jetzt in Community Tech Preview 2) verfügt über diese Funktion, die als Job (früher PSJob) bezeichnet wird. Erfahren Sie mehr darüber hier oder hier .
  3. Sie können es tatsächlich tun auf die harte Tour in v1, fühlen Sie sich frei, es zu haben, aber ich habe mich nie darum gekümmert.
37
halr9000

Solange der Befehl eine ausführbare Datei oder eine Datei ist, der eine ausführbare Datei zugeordnet ist, verwenden Sie Start-Process (verfügbar ab Version 2):

Start-Process -NoNewWindow ping google.com

Sie können dies auch als Funktion in Ihr Profil einfügen:

function bg() {Start-Process -NoNewWindow @args}

und dann wird der Aufruf:

bg ping google.com

Meiner Meinung nach ist Start-Job ein Overkill für den einfachen Anwendungsfall, einen Prozess im Hintergrund auszuführen:

  1. Start-Job hat keinen Zugriff auf Ihren vorhandenen Bereich (da er in einer separaten Sitzung ausgeführt wird). Du kannst "Start-Job {notepad $ myfile}" nicht ausführen
  2. Start-Job behält das aktuelle Verzeichnis nicht bei (da es in einer separaten Sitzung ausgeführt wird). Sie können "Start-Job {notepad myfile.txt}" nicht ausführen, wenn sich myfile.txt im aktuellen Verzeichnis befindet.
  3. Die Ausgabe wird nicht automatisch angezeigt. Sie müssen Receive-Job mit der ID des Jobs als Parameter ausführen.

HINWEIS: In Bezug auf Ihr erstes Beispiel würde "bg sleep 30" nicht funktionieren, da sleep ein Powershell-Commandlet ist. Start-Process funktioniert nur, wenn Sie tatsächlich einen Prozess gegabelt haben.

109
Bogdan Calmac

Es scheint, dass der an Start-Job Übergebene Skriptblock nicht mit demselben aktuellen Verzeichnis wie der Befehl Start-Job Ausgeführt wird. Geben Sie daher bei Bedarf den vollständig qualifizierten Pfad an.

Beispielsweise:

Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }
20
ps2> start-job {start-sleep 20}

ich habe noch nicht herausgefunden, wie man stdout in Echtzeit erhält. start-job erfordert, dass Sie stdout mit get-job abfragen

update: Ich konnte nicht einfach anfangen zu tun, was ich will, was im Grunde der Bash & Operator ist. Hier ist mein bisher bester Hack

PS> notepad $profile #edit init script -- added these lines
function beep { write-Host `a }
function ajp { start powershell {ant Java-platform|out-null;beep} } #new window, stderr only, beep when done
function acjp { start powershell {ant clean Java-platform|out-null;beep} }
PS> . $profile #re-load profile script
PS> ajp
19
Dustin Getz

Sie können PowerShell-Job-Cmdlets verwenden, um Ihre Ziele zu erreichen.

In PowerShell sind 6 auftragsbezogene Cmdlets verfügbar.

  • Arbeit bekommen
    • Ruft Windows PowerShell-Hintergrundjobs ab, die in der aktuellen Sitzung ausgeführt werden
  • Receive-Job
    • Ruft die Ergebnisse der Windows PowerShell-Hintergrundjobs in der aktuellen Sitzung ab
  • Remove-Job
    • Löscht einen Windows PowerShell-Hintergrundjob
  • Start-Job
    • Startet einen Windows PowerShell-Hintergrundjob
  • Stop-Job
    • Stoppt einen Windows PowerShell-Hintergrundjob
  • Wait-Job
    • Unterdrückt die Eingabeaufforderung, bis einer oder alle in der Sitzung ausgeführten Windows PowerShell-Hintergrundjobs abgeschlossen sind

Wenn Sie daran interessiert sind, können Sie das Beispiel herunterladen So erstellen Sie einen Hintergrundjob in PowerShell

12
Eric

Ab PowerShell Core 6.0 können Sie am Ende des Befehls & Schreiben. Dies entspricht dem Ausführen der Pipeline im Hintergrund im aktuellen Arbeitsverzeichnis .

Es ist nicht gleichbedeutend mit & In Bash, es ist nur eine schönere Syntax für die aktuelle PowerShell jobs -Funktion. Es gibt ein Jobobjekt zurück, sodass Sie alle anderen Befehle verwenden können, die Sie für Jobs verwenden würden. Zum Beispiel Receive-Job:

C:\utils> ping google.com &

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
35     Job35           BackgroundJob   Running       True            localhost            Microsoft.PowerShell.M...


C:\utils> Receive-Job 35

Pinging google.com [172.217.16.14] with 32 bytes of data:
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=11ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55
Reply from 172.217.16.14: bytes=32 time=10ms TTL=55

Ping statistics for 172.217.16.14:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 10ms, Maximum = 11ms, Average = 10ms
C:\utils>

Wenn Sie einige Anweisungen im Hintergrund ausführen möchten, können Sie den & - Aufrufoperator , { } - Skriptblock und diesen neuen & - Hintergrund kombinieren Betreiber wie hier:

& { cd .\SomeDir\; .\SomeLongRunningOperation.bat; cd ..; } &

Weitere Informationen finden Sie auf den Dokumentationsseiten:

von Was ist neu in PowerShell Core 6.0 :

Unterstützt Hintergrundinformationen von Pipelines mit kaufmännischem Und (&) (# 3360)

Wenn Sie & Am Ende einer Pipeline einfügen, wird die Pipeline als PowerShell-Job ausgeführt. Wenn eine Pipeline im Hintergrund ausgeführt wird, wird ein Jobobjekt zurückgegeben. Sobald die Pipeline als Job ausgeführt wird, können alle Standard-Cmdlets *-Job Zum Verwalten des Jobs verwendet werden. In der Pipeline verwendete Variablen (ohne Berücksichtigung prozessspezifischer Variablen) werden automatisch in den Job kopiert, sodass Copy-Item $foo $bar & Nur funktioniert. Der Job wird auch im aktuellen Verzeichnis anstelle des Basisverzeichnisses des Benutzers ausgeführt. Weitere Informationen zu PowerShell-Jobs finden Sie unter about_Jobs .

von about_operators/Und-Zeichen-Hintergrundoperator & :

Und-Zeichen-Hintergrundoperator &

Führt die Pipeline vor einem PowerShell-Auftrag aus. Der kaufmännische Und-Hintergrundoperator verhält sich ähnlich wie der UNIX-Kaufmännische Und-Hintergrundoperator, der den Befehl als Hintergrundprozess ausführt. Der kaufmännische Hintergrundoperator baut auf PowerShell-Jobs auf, sodass er mit Start-Job Viele Funktionen gemeinsam hat. Der folgende Befehl enthält die grundlegende Verwendung des Und-Zeichen-Hintergrundoperators.

Get-Process -Name pwsh &

Dies entspricht funktional der folgenden Verwendung von Start-Job.

Start-Job -ScriptBlock {Get-Process -Name pwsh}

Da dies funktional der Verwendung von Start-Job Entspricht, gibt der kaufmännische Hintergrundoperator genau wie Start-Job does Ein Job -Objekt zurück. Dies bedeutet, dass Sie Receive-Job Und Remove-Job Genauso verwenden können, als hätten Sie Start-Job Zum Starten des Jobs verwendet.

$job = Get-Process -Name pwsh &
Receive-Job $job

Ausgabe

NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
------    -----      -----     ------      --  -- -----------
    0     0.00     221.16      25.90    6988 988 pwsh
    0     0.00     140.12      29.87   14845 845 pwsh
    0     0.00      85.51       0.91   19639 988 pwsh


$job = Get-Process -Name pwsh &
Remove-Job $job

Weitere Informationen zu PowerShell-Jobs finden Sie unter about_Jobs .

8

Ich habe die hier beschriebene Lösung http://jtruher.spaces.live.com/blog/cns!7143DA6E51A2628D!130.entry erfolgreich in PowerShell v1.0 verwendet. In PowerShell v2.0 wird es definitiv einfacher.

0
Jeffery Hicks

Sie können so etwas tun.

$a = start-process -NoNewWindow powershell {timeout 10; 'done'} -PassThru

done

Und wenn Sie darauf warten wollen:

$a | wait-process

Bonus OSX oder Linux Version:

$a = start-process pwsh '-c',{start-sleep 5; 'done'} -PassThru 
0
js2010