백그라운드 프로세스 포크 / 실행을위한 bash 앰퍼샌드 (&)와 동등한 Powershell


157

bash에서는 앰퍼샌드 (&)를 사용하여 백그라운드에서 명령을 실행하고 명령 실행이 완료되기 전에 대화식 제어를 사용자에게 반환 할 수 있습니다. Powershell에서 이와 동등한 방법이 있습니까?

bash에서의 사용 예 :

 sleep 30 &

답변:


123

명령이 실행 파일이거나 관련 실행 파일이있는 파일 인 경우 Start-Process (v2에서 사용 가능)를 사용 하십시오 .

Start-Process -NoNewWindow ping google.com

이것을 프로파일에 함수로 추가 할 수도 있습니다.

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

그러면 호출은 다음과 같습니다.

bg ping google.com

제 생각에는 Start-Job은 백그라운드에서 프로세스를 실행하는 간단한 사용 사례에 대한 과잉입니다.

  1. Start-Job은 별도의 세션에서 실행되기 때문에 기존 범위에 액세스 할 수 없습니다. "Start-Job {notepad $ myfile}"을 수행 할 수 없습니다.
  2. Start-Job은 별도의 세션에서 실행되기 때문에 현재 디렉토리를 유지하지 않습니다. myfile.txt가 현재 디렉토리에있는 "Start-Job {notepad myfile.txt}"를 수행 할 수 없습니다.
  3. 출력이 자동으로 표시되지 않습니다. 작업 ID를 매개 변수로 Receive-Job을 실행해야합니다.

참고 : 초기 예제와 관련하여 절전 모드는 Powershell 커맨드 렛이므로 "bg sleep 30"이 작동하지 않습니다. 시작 프로세스는 실제로 프로세스를 분기 할 때만 작동합니다.


7
이 답변을 찾았습니다. 나는 유닉스 포크 두 메커니즘과 동등한 것을 찾고있었습니다. 나에게 Start-JobPS 셸이 종료되면 시작된 것이 사라질 것 같습니다 . 반대로 Start-ProcessPS 쉘이 종료 된 후에 시작된 것이 계속 실행될 것 같습니다 . 이것은 차이입니다.
peterh

예-를 사용하여 스크립트를 시작 Start-Process하면 셸 종료에서도 유지되지만 콘솔 창에서 시작한 경우 해당 창에 바인딩 된 상태로 유지되고 창을 닫으면 프로세스가 종료됩니다.
거스

1
그러나 출력 리디렉션을 수행 할 수 없으므로 Start-Process작동하지 않습니다 Start-Process {ping -n 1000 example.com > ping__example.com.txt }. 와 똑같은 Start-Job작품 벌금 (출력 파일에 대한 전체 경로를 사용해야하지만).
Nux

1
노드 웹 서버를 실행하려고 시도했으며 powershell을 종료하면 프로세스가 종료됩니다. 아무도 이유를 아십니까?
Jel

@Jel No, 그러나 Guss의 의견은 그것에 대해 이야기합니다.
jpaugh

26

전달 된 스크립트 블록 Start-JobStart-Job명령 과 동일한 현재 디렉토리로 실행되지 않는 것 같으 므로 필요한 경우 완전한 경로를 지정하십시오.

예를 들면 다음과 같습니다.

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

3
예를 들어 명령 줄에서 Git Pull을 실행 해야하는 경우 모든 것에 대한 전체 경로를 지정해야합니다 ...? 정말 성가신 일입니다.
CMCDragonkai

1
고마워, 좋은 팁, 실행되지 않는 작업으로 돌아 다니는 것이 이유였습니다.
옴니

@CMCDragonkai 또는 Start-Job {cd C : \ Path \ To \ Repo; 자식 풀}
Mahomedalid

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

나는 아직 stdout을 실시간으로 얻는 방법을 알지 못했지만 start-job은 stdout을 get-job과 폴링해야합니다.

업데이트 : 기본적으로 bash & operator 인 원하는 작업을 쉽게 수행 할 수 없습니다. 여기까지 내 최고의 해킹이 있습니다.

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
PowerShell v3.0부터 다음과 같이 실시간으로 stdout을 얻을 수 있습니다.Start-Job { Write-Output 'Hello world' } | Receive-Job -Wait
JamesQMurphy

19

PowerShell Core 6.0 &에서는 명령 끝 에서 쓸 수 있으며 현재 작업 디렉토리에서 백그라운드로 파이프 라인을 실행하는 것과 같습니다 .

&bash 와 동일하지 않으며 현재 PowerShell 작업 기능에 대한 더 좋은 구문 일뿐 입니다. 작업 오브젝트를 리턴하므로 작업에 사용할 다른 모든 명령을 사용할 수 있습니다. 예를 들면 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>

백그라운드에서 몇 개의 명령문을 실행하려면 &call 연산자 , { }스크립트 블록 및이 새로운 &background 연산자를 다음 과 같이 결합 할 수 있습니다.

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

다음은 설명서 페이지의 추가 정보입니다.

에서 PowerShell을 코어 6.0의 새로운 기능 :

앰퍼샌드 (&)를 사용하여 파이프 라인의 백그라운드 지원 (# 3360)

&파이프 라인의 끝에 배치 하면 파이프 라인이 PowerShell 작업으로 실행됩니다. 파이프 라인이 백그라운드이면 작업 오브젝트가 리턴됩니다. 파이프 라인이 작업으로 실행되면 모든 표준 *-Jobcmdlet을 사용하여 작업을 관리 할 수 ​​있습니다. 파이프 라인에 사용 된 변수 (프로세스 별 변수 무시)는 작업에 자동으로 복사되므로 Copy-Item $foo $bar &작동합니다. 작업은 사용자의 홈 디렉토리 대신 현재 디렉토리에서 실행됩니다. PowerShell 작업에 대한 자세한 내용은 about_Jobs를 참조 하십시오 .

about_operators / 앰퍼샌드 배경 오퍼레이터 :

앰퍼샌드 백그라운드 연산자 &

PowerShell 작업에서 파이프 라인을 실행하기 전에 파이프 라인을 실행합니다. 앰퍼샌드 백그라운드 연산자는 백그라운드 프로세스로 명령을 실행하기 전에 UNIX "앰퍼샌드 연산자"와 유사하게 작동합니다. 앰퍼샌드 백그라운드 연산자는 PowerShell 작업 위에 구축되어 많은 기능을 공유합니다 Start-Job. 다음 명령에는 앰퍼샌드 백그라운드 연산자의 기본 사용법이 포함되어 있습니다.

Get-Process -Name pwsh &

이것은 기능적으로 다음의 사용법과 동일합니다 Start-Job.

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

그것을 사용하여 동일한 기능이기 때문에 Start-Job, 앰퍼샌드 배경 연산자는 반환 Job단지와 같은 개체를 Start-Job does. 당신이 사용할 수있는이 수단 Receive-JobRemove-Job당신이 당신이 사용했던 경우와 마찬가지로 Start-Job작업을 시작합니다.

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

산출

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

PowerShell 작업에 대한 자세한 내용은 about_Jobs를 참조 하십시오 .


1
MS 페이지 100 개를 달성 할 수 없다는이 훌륭한 요약에 감사드립니다.
not2qubit

콘솔 작업 을 처리하는 방법에 대한 아이디어가 있습니까? 위의으로 시도 Receive-Job 3했지만 아무 일도 일어나지 않습니다.
not2qubit

@ not2qubit " 콘솔 작업"의 의미를 잘 모르겠습니다 . 백그라운드에서 실행하려는 명령은 무엇입니까?
Mariusz Pawelski

Windows 콘솔을 시작하는 앱을 사용하고 있었지만 출력을 얻을 수 없으며 * foreground에 작업을 가져 오기 위해 nix 세계fg 와 유사하게 그것을 기대하고있었습니다 .
not2qubit

@ not2qubit 불행히도 fgpowershell 에는 유닉스와 비슷한 것이없는 것 같습니다 : (나는 그것을 찾았지만 아무것도 찾을 수 없었습니다)
Mariusz Pawelski

17

PowerShell 작업 cmdlet을 사용하여 목표를 달성 할 수 있습니다.

PowerShell에는 6 가지 작업 관련 cmdlet이 있습니다.

  • Get-Job
    • 현재 세션에서 실행중인 Windows PowerShell 백그라운드 작업을 가져옵니다.
  • 직업을 받기
    • 현재 세션에서 Windows PowerShell 백그라운드 작업의 결과를 가져옵니다.
  • 제거 작업
    • Windows PowerShell 백그라운드 작업을 삭제합니다.
  • 작업 시작
    • Windows PowerShell 백그라운드 작업을 시작합니다.
  • 스톱 잡
    • Windows PowerShell 백그라운드 작업을 중지합니다.
  • 잠깐만
    • 세션에서 실행중인 하나 또는 모든 Windows PowerShell 백그라운드 작업이 완료 될 때까지 명령 프롬프트를 표시하지 않습니다.

흥미가 있다면 PowerShell에서 백그라운드 작업을 만드는 방법 샘플을 다운로드 할 수 있습니다.


1
Powershell 3 이상을 다룰 때 좋은 대답입니다. 작업 cmdlet과 이전 답변의 차이점은 무엇입니까?
Jeremy Hajek

3

이런 식으로 할 수 있습니다.

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

그리고 당신이 그것을 기다리고 싶다면 :

$a | wait-process

보너스 OSX 또는 리눅스 버전 :

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

내가 가지고있는 pinger 스크립트의 예. 인수는 배열로 전달됩니다.

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

start 프로세스를 포크하고 제어를 호출자에게 리턴합니다. 자세한 정보는 여기에
Aethalides

@Aethalides start는 실제로 powershell의 start-process에 대한 별칭입니다.
js2010


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.