Powershell equivalente ao bash e comercial (&) para bifurcação / execução de processos em segundo plano


158

No bash, o e comercial (&) pode ser usado para executar um comando em segundo plano e retornar o controle interativo ao usuário antes que o comando termine a execução. Existe um método equivalente para fazer isso no Powershell?

Exemplo de uso no bash:

 sleep 30 &

Respostas:


124

Desde que o comando seja um executável ou um arquivo que tenha um executável associado, use Start-Process (disponível na v2):

Start-Process -NoNewWindow ping google.com

Você também pode adicionar isso como uma função no seu perfil:

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

e então a invocação se torna:

bg ping google.com

Na minha opinião, Start-Job é um exagero para o caso de uso simples de executar um processo em segundo plano:

  1. O Start-Job não tem acesso ao seu escopo existente (porque é executado em uma sessão separada). Você não pode executar "Iniciar tarefa {bloco de notas $ myfile}"
  2. Start-Job não preserva o diretório atual (porque é executado em uma sessão separada). Você não pode executar "Start-Job {bloco de notas myfile.txt}" onde myfile.txt está no diretório atual.
  3. A saída não é exibida automaticamente. Você precisa executar o Receive-Job com o ID do trabalho como parâmetro.

NOTA: Em relação ao seu exemplo inicial, "bg sleep 30" não funcionaria porque sleep é um comando do Powershell. Start-Process só funciona quando você realmente bifurca um processo.


7
Ainda bem que encontrei esta resposta. Eu estava procurando o equivalente a um mecanismo Unix fork-two. Para mim, parece que algo iniciado com Start-Jobserá morto quando o shell PS sair. Em contraste, parece que algo iniciado com Start-Processcontinuará sendo executado após a saída do shell do PS. Essa é uma grande diferença.
Peterh

Sim - se você iniciar um script usando Start-Process, ele sobreviverá ao encerramento do shell, mas se você o iniciou a partir de uma janela do console, ele permanecerá vinculado a essa janela e o fechamento da janela encerrará o processo.
Guss

1
Nota, porém, que você não pode fazer o redirecionamento de saída com Start-Processe por isso este trabalho não vai: Start-Process {ping -n 1000 example.com > ping__example.com.txt }. A mesma coisa Start-Jobfunciona bem (embora você precise usar o caminho completo para o arquivo de saída).
Nux

1
Tentou fazer isso para executar um servidor da web do nó e o processo termina quando eu saio do PowerShell. Alguém sabe o porquê?
Jel

@ Jo Não, mas o comentário de Guss fala sobre isso.
jpaugh

26

Parece que o bloco de script passado Start-Jobnão é executado com o mesmo diretório atual do Start-Jobcomando, portanto, especifique o caminho completo, se necessário.

Por exemplo:

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

3
Por exemplo, se eu precisar executar o Git Pull na linha de comando, preciso especificar o caminho completo para tudo ...? Isso é realmente irritante.
precisa saber é o seguinte

1
obrigado, ótima dica, andamos por aí com um trabalho que não funcionaria, esse foi o motivo.
Omni

@CMCDragonkai ou você pode fazer apenas o Start-Job {cd C: \ Path \ To \ Repo; git pull}
Mahomedalid

21
ps2> start-job {start-sleep 20}

Ainda não descobri como obter o stdout em tempo real, o start-job exige que você pesquise stdout com o get-job

update: não consegui iniciar o trabalho para fazer facilmente o que quero, que é basicamente o bash & operator. aqui está o meu melhor hack até agora

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

1
A partir do PowerShell v3.0, você pode obter stdout em tempo real como este:Start-Job { Write-Output 'Hello world' } | Receive-Job -Wait
JamesQMurphy

19

No PowerShell Core 6.0, você pode gravar &no final do comando e será equivalente à execução do pipeline em segundo plano no diretório de trabalho atual .

Não é equivalente &no bash, é apenas uma sintaxe melhor para o recurso atual de trabalhos do PowerShell . Ele retorna um objeto de trabalho para que você possa usar todos os outros comandos que usaria para trabalhos. Por exemplo 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>

Se você deseja executar algumas instruções em segundo plano, pode combinar &o operador de chamada , o { }bloco de scripts e esse novo &operador de segundo plano, como aqui:

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

Aqui estão mais algumas informações das páginas de documentação:

do Novidades do PowerShell Core 6.0 :

Suporte ao background de dutos com e comercial (&) (# 3360)

Colocar &no final de um pipeline faz com que ele seja executado como um trabalho do PowerShell. Quando um pipeline está em segundo plano, um objeto de trabalho é retornado. Depois que o pipeline estiver sendo executado como um trabalho, todos os *-Jobcmdlets padrão podem ser usados ​​para gerenciar o trabalho. As variáveis ​​(ignorando variáveis ​​específicas do processo) usadas no pipeline são copiadas automaticamente para o trabalho, para que Copy-Item $foo $bar &funcionem. O trabalho também é executado no diretório atual em vez do diretório inicial do usuário. Para obter mais informações sobre tarefas do PowerShell, consulte about_Jobs .

from about_operators / Operador em segundo plano Ampersand & :

Operador de fundo e comercial e

Executa o pipeline antes dele em um trabalho do PowerShell. O operador em segundo plano e comercial atua de maneira semelhante ao "operador e comercial" do UNIX, que famosa executa o comando antes dele como um processo em segundo plano. O operador em segundo plano e comercial é construído sobre as tarefas do PowerShell, de modo que ele compartilha muitas funcionalidades Start-Job. O comando a seguir contém o uso básico do operador em segundo plano e comercial.

Get-Process -Name pwsh &

Isso é funcionalmente equivalente ao seguinte uso de Start-Job.

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

Como é funcionalmente equivalente ao uso Start-Job, o operador em segundo plano e comercial retorna um Jobobjeto da mesma forma Start-Job does. Isso significa que você é capaz de usar Receive-Jobe Remove-Jobcomo faria se tivesse Start-Jobiniciado o trabalho.

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

Resultado

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

Para obter mais informações sobre tarefas do PowerShell, consulte about_Jobs .


1
Obrigado por este excelente resumo que centenas de páginas da MS não conseguiram realizar.
Not2qubit

Alguma idéia de como lidar com trabalhos de console ? Eu tentei o acima com Receive-Job 3, mas nada acontece.
Not2qubit

@ not2qubit Não sei ao certo o que você quer dizer com " trabalhos de console ". Que comando você executa e deseja executar em segundo plano?
Mariusz Pawelski 5/02/19

Eu estava usando um aplicativo que inicia um console do Windows, mas não consigo obter nenhuma saída e esperava obtê-la de maneira semelhante ao mundo nix fgpor trazer trabalho para o primeiro plano .
Not2qubit

@ not2qubit Infelizmente, parece que não existe tal coisa semelhante ao unix fgno PowerShell :( Lembro-me de olhar para ele, mas não consegui encontrar nada
Mariusz Pawelski

17

Você pode usar os cmdlets de tarefa do PowerShell para atingir seus objetivos.

Existem 6 cmdlets relacionados ao trabalho disponíveis no PowerShell.

  • Conseguir emprego
    • Obtém os trabalhos em segundo plano do Windows PowerShell em execução na sessão atual
  • Receive-Job
    • Obtém os resultados dos trabalhos em segundo plano do Windows PowerShell na sessão atual
  • Remove-Job
    • Exclui um trabalho em segundo plano do Windows PowerShell
  • Start-Job
    • Inicia um trabalho em segundo plano do Windows PowerShell
  • Stop-Job
    • Interrompe um trabalho em segundo plano do Windows PowerShell
  • Wait-Job
    • Suprime o prompt de comando até que uma ou todas as tarefas em segundo plano do Windows PowerShell em execução na sessão sejam concluídas

Se interessante, você pode baixar o exemplo Como criar um trabalho em segundo plano no PowerShell


1
Boa resposta, pois trata do Powershell 3+. Qual é a diferença entre os cmdlets de tarefas e as respostas anteriores?
Jeremy Hajek 01/01

3

Você pode fazer algo assim.

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

E se você quiser esperar por isso:

$a | wait-process

Versão bônus osx ou linux:

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

Exemplo de script pinger que eu tenho. Os argumentos são passados ​​como uma matriz:

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

start bifurcará o processo e retornará o controle ao chamador. Mais informações aqui
Aethalides

O @Aethalides start é na verdade um apelido para o processo de início no PowerShell.
precisa saber é o seguinte


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.