Powershell-equivalent van bash ampersand (&) voor forking/running achtergrondprocessen

In bash kan het ampersand (&) worden gebruikt om een ​​opdracht op de achtergrond uit te voeren en interactieve controle terug te geven aan de gebruiker voordat de opdracht is uitgevoerd. Is er een gelijkwaardige methode om dit te doen in Powershell?

Voorbeeld van gebruik in bash:

sleep 30 &

Antwoord 1, autoriteit 100%

Zolang de opdracht een uitvoerbaar bestand is of een bestand met een bijbehorend uitvoerbaar bestand, gebruikt u Start-Process(beschikbaar vanaf v2):

Start-Process -NoNewWindow ping google.com

Je kunt dit ook als functie toevoegen aan je profiel:

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

en dan wordt de aanroep:

bg ping google.com

Naar mijn mening is Start-Job een overkill voor het simpele gebruik van een proces op de achtergrond:

  1. Start-Job heeft geen toegang tot uw bestaande scope (omdat deze in een aparte sessie wordt uitgevoerd). U kunt “Start-Job {notepad $myfile}”
  2. . niet uitvoeren

  3. Start-Job bewaart de huidige directory niet (omdat deze in een aparte sessie wordt uitgevoerd). U kunt “Start-Job {notepad myfile.txt}” niet uitvoeren waar myfile.txt zich in de huidige map bevindt.
  4. De uitvoer wordt niet automatisch weergegeven. U moet Receive-Job uitvoeren met de ID van de taak als parameter.

OPMERKING: Wat betreft uw eerste voorbeeld, “bg sleep 30” zou niet werken omdat sleep een Powershell-commando is. Start-Process werkt alleen als je een proces daadwerkelijk afsplitst.


Antwoord 2, autoriteit 26%

Vanuit PowerShell Core 6.0 kunt u &schrijven aan het einde van de opdracht en dit komt overeen met het uitvoeren van uw pijplijn op de achtergrond in de huidige werkmap.

Het is niet gelijk aan &in bash, het is gewoon een mooiere syntaxis voor de huidige PowerShell jobs-functie. Het retourneert een taakobject, zodat u alle andere opdrachten kunt gebruiken die u voor taken zou gebruiken. Bijvoorbeeld 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>

Als je een paar instructies op de achtergrond wilt uitvoeren, kun je &oproepoperator, { }scriptbloken dit nieuwe &achtergrondoperatorzoals hier:

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

Hier is wat meer informatie van documentatiepagina’s:

van Wat is er nieuw in PowerShell Core 6.0:

Ondersteuning van achtergrondvorming van pijpleidingen met ampersand (&) (#3360)

Als u &aan het einde van een pijplijn plaatst, wordt de pijplijn uitgevoerd als een PowerShell-taak. Wanneer een pijplijn op de achtergrond is, wordt een taakobject geretourneerd. Zodra de pijplijn als taak wordt uitgevoerd, kunnen alle standaard *-Job-cmdlets worden gebruikt om de taak te beheren. Variabelen (waarbij processpecifieke variabelen worden genegeerd) die in de pijplijn worden gebruikt, worden automatisch naar de taak gekopieerd, zodat Copy-Item $foo $bar &gewoon werkt. De taak wordt ook uitgevoerd in de huidige directory in plaats van in de homedirectory van de gebruiker. Voor meer informatie over PowerShell-taken, zie about_Jobs.

van about_operators / Ampersand-achtergrondoperator &:

Ampersand-achtergrondoperator &

Voert de pijplijn ervoor uit in een PowerShell-taak. De ampersand-achtergrondoperator werkt op dezelfde manier als de UNIX “ampersand-operator”, die de beroemde opdracht ervoor uitvoert als een achtergrondproces. De ampersand-achtergrondoperator is bovenop PowerShell-taken gebouwd en deelt dus veel functionaliteit met Start-Job. De volgende opdracht bevat het basisgebruik van de en-teken-achtergrondoperator.

Get-Process -Name pwsh &

Dit is functioneel equivalent aan het volgende gebruik van Start-Job.

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

Omdat het functioneel equivalent is aan het gebruik van Start-Job, retourneert de en-teken-achtergrondoperator een Job-object, net zoals Start-Job does. Dit betekent dat u Receive-Joben Remove-Jobkunt gebruiken net zoals u zou doen als u Start-Jobhad gebruikt om de baan.

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

Uitvoer

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

Voor meer informatie over PowerShell-taken, zie about_Jobs.


Antwoord 3, autoriteit 20%

Het lijkt erop dat het scriptblok dat wordt doorgegeven aan Start-Jobniet wordt uitgevoerd met dezelfde huidige map als de opdracht Start-Job, dus zorg ervoor dat u een volledig gekwalificeerd pad opgeeft indien nodig.

Bijvoorbeeld:

Start-Job { C:\absolute\path\to\command.exe --afileparameter C:\absolute\path\to\file.txt }

Antwoord 4, autoriteit 15%

ps2> start-job {start-sleep 20}

ik ben er nog niet achter hoe ik stdout in realtime kan krijgen, start-job vereist dat je stdout pollt met get-job

update: ik kon de taak niet starten om gemakkelijk te doen wat ik wil, wat in feite de bash & exploitant. hier is mijn beste hack tot nu toe

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

Antwoord 5, autoriteit 14%

U kunt PowerShell-taak-cmdlets gebruiken om uw doelen te bereiken.

Er zijn 6 taakgerelateerde cmdlets beschikbaar in PowerShell.

  • Get-job
    • Krijgt Windows PowerShell-achtergrondtaken die in de huidige sessie worden uitgevoerd
  • Vacature ontvangen
    • Krijgt de resultaten van de Windows PowerShell-achtergrondtaken in de huidige sessie
  • Taak verwijderen
    • Verwijdert een Windows PowerShell-achtergrondtaak
  • Start-Job
    • Start een Windows PowerShell-achtergrondtaak
  • Stop-Job
    • Stopt een Windows PowerShell-achtergrondtaak
  • Wacht-Job
    • Onderdrukt de opdrachtprompt totdat een of alle Windows PowerShell-achtergrondtaken die in de sessie worden uitgevoerd, zijn voltooid

Als je er interesse in hebt, kun je het voorbeeld downloaden Hoe een achtergrond te maken baan in PowerShell


Antwoord 6, autoriteit 4%

Je kunt zoiets als dit doen.

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

En als je erop wilt wachten:

$a | wait-process

Bonus osx- of linux-versie:

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

Voorbeeld van een pingerscript dat ik heb. De argumenten worden doorgegeven als een array:

$1 = start -n powershell pinger,comp001 -pa

Antwoord 7, autoriteit 3%

tl;dr

Start-Process powershell { sleep 30 }

Antwoord 8

Ik heb de hier beschreven oplossing gebruikt http://jtruher .spaces.live.com/blog/cns!7143DA6E51A2628D!130.entrysuccesvol in PowerShell v1.0. Het zal zeker gemakkelijker zijn in PowerShell v2.0.

Other episodes