Arka plan işlemlerini çatallamak / çalıştırmak için bas ve işaretinin (&) Powershell eşdeğeri


159

Bash'da ve işareti (&), arka planda bir komut çalıştırmak ve komutun çalışması bitmeden önce kullanıcıya etkileşimli kontrolü döndürmek için kullanılabilir. Powershell'de bunu yapmanın eşdeğer bir yöntemi var mı?

Bash kullanım örneği:

 sleep 30 &

Yanıtlar:


126

Komut bir yürütülebilir dosya veya ilişkilendirilmiş bir yürütülebilir dosyaya sahip bir dosya olduğu sürece, Start-Process (v2'den edinilebilir) kullanın:

Start-Process -NoNewWindow ping google.com

Bunu profilinizde bir işlev olarak da ekleyebilirsiniz:

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

ve sonra çağırma olur:

bg ping google.com

Kanımca, Start-Job, arka planda bir işlem yürütmenin basit kullanım durumu için aşırıya kaçmadır:

  1. Start-Job'un mevcut kapsamınıza erişimi yoktur (ayrı bir oturumda çalıştığı için). "Start-Job {notepad $ myfile}" yapamazsınız
  2. Start-Job geçerli dizini korumaz (ayrı bir oturumda çalıştığı için). Myfile.txt dosyasının geçerli dizinde olduğu "Start-Job {notepad myfile.txt}" yapamazsınız.
  3. Çıkış otomatik olarak gösterilmez. Alma İşini parametre olarak işin kimliğiyle çalıştırmanız gerekir.

NOT: İlk örneğinizle ilgili olarak, uyku bir Powershell komut dosyası olduğu için "bg sleep 30" çalışmaz. Başlatma İşlemi yalnızca bir işlemi gerçekten çatalladığınızda çalışır.


7
Bu cevabı bulduğuma sevindim. Bir Unix çatal-iki mekanizmasının eşdeğerini arıyordum. Bana öyle geliyor ki Start-JobPS kabuğu çıktığında bir şey öldürülecek. Buna karşılık Start-Process, PS kabuğu çıktıktan sonra bir şeylerin çalışmaya devam edeceği görülüyor . Bu büyük bir fark.
peterh

Evet - bir komut dosyasını kullanarak başlatırsanız Start-Process, kabuk sonlandırmasından sağ çıkacaktır, ancak bir konsol penceresinden başlattıysanız, o pencereye bağlı kalır ve pencereyi kapatmak işlemi sonlandırır.
Guss

1
Birlikte çıkış yönlendirme yapamaz ancak o Not Start-Processve bu EDİLMEYEN işin bu yüzden: Start-Process {ping -n 1000 example.com > ping__example.com.txt }. Aynı şey Start-Jobiyi çalışır (ancak çıkış dosyasının tam yolunu kullanmanız gerekir).
Nux

1
Bir düğüm web sunucusu çalıştırmak için bunu yapmaya çalıştı ve ben powershell çıktığınızda işlem sona erer. Nedenini bilen var mı?
Jel

@Jel Hayır, ama Guss'un yorumu bundan bahsediyor.
jpaugh

26

Aktarılan komut dosyası bloğunun komutla Start-Jobaynı geçerli dizinde yürütülmediği anlaşılıyor Start-Job, bu nedenle gerekirse tam yol belirttiğinizden emin olun.

Örneğin:

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

3
Bu yüzden örneğin Git Pull'u komut satırında çalıştırmam gerekirse, her şeyin tam yolunu belirtmem gerekir ...? Bu gerçekten sinir bozucu.
CMCDragonkai

1
teşekkürler, büyük ipucu, çalışmayan bir iş ile dolaşmak, nedeni bu idi.
Omni

@CMCDragonkai ya da sadece Start-Job {cd C: \ Path \ To \ Repo; git pull}
Mahomedalid

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

henüz gerçek zamanlı olarak stdout almak için nasıl anlamadım, başlangıç-iş almak stdout almak-iş gerektirir

Güncelleme: Temelde bash ve operatör olan istediğimi kolayca yapmak için işe başlayamadım. işte şimdiye kadarki en iyi hack'im

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 Start-Job { Write-Output 'Hello world' } | Receive-Job -Wait
v3.0'dan itibaren

19

PowerShell Core 6.0'dan &komutun sonunda yazabilirsiniz ve mevcut çalışma dizininde boru hattını arka planda çalıştırmaya eşdeğer olacaktır .

Bu &bash ile eşdeğer değil , mevcut PowerShell işleri özelliği için sadece daha hoş bir sözdizimi . Bir iş nesnesi döndürür, böylece işler için kullanacağınız diğer tüm komutları kullanabilirsiniz. Örneğin 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>

Arka planda birkaç ifade yürütmek istiyorsanız, &çağrı operatörünü , { }komut dosyası bloğunu ve bu yeni &arka plan operatörünü aşağıdaki gibi birleştirebilirsiniz:

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

Doküman sayfalarından biraz daha bilgi:

dan PowerShell Çekirdek 6.0 Neler Yeni :

Ve işareti ile boru hatlarının arka planını destekleme (&) (# 3360)

&Bir boru hattının sonuna koymak , boru hattının bir PowerShell işi olarak çalıştırılmasına neden olur. Bir ardışık düzen arka planlandığında, bir iş nesnesi döndürülür. Boru hattı bir iş olarak çalıştığında *-Job, işi yönetmek için tüm standart cmdlet'ler kullanılabilir. Boru hattında kullanılan değişkenler (işleme özgü değişkenleri yok saymak) işe otomatik olarak kopyalanır, böylece Copy-Item $foo $bar &çalışır. İş ayrıca kullanıcının ana dizini yerine geçerli dizinde çalıştırılır. PowerShell işleri hakkında daha fazla bilgi için, bkz. About_Jobs .

den about_operators / Ve işareti arka operatörü ve :

Ve işareti arka plan operatörü &

Boru hattını bir PowerShell işinden önce çalıştırır. Ve işareti arka plan işleci, komutu arka planda bir işlem olarak yürüten UNIX "ve işareti işlecine" benzer şekilde davranır. Ve işareti arka plan operatörü, PowerShell işlerinin üzerine inşa edilmiştir, böylece birçok işlevselliği paylaşır Start-Job. Aşağıdaki komut, ve işareti arka plan işlecinin temel kullanımını içerir.

Get-Process -Name pwsh &

Bu, işlevsel olarak aşağıdaki kullanımıyla eşdeğerdir Start-Job.

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

İşlevsel olarak kullanıma eşdeğer olduğundan Start-Job, ve işareti arka plan operatörü Jobtıpkı bir nesneyi döndürür Start-Job does. Kullanmak edebiliyoruz Bu araçlar Receive-Jobve Remove-Jobsadece kullandığınız olsaydı yaptığınız gibi Start-Jobişe başlamak için.

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

Çıktı

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 işleri hakkında daha fazla bilgi için bkz. About_Jobs .


1
100 sayfanın MS sayfalarının başaramadığı bu harika özet için teşekkürler.
not2qubit

Konsol işlerinin nasıl ele alınacağı hakkında bir fikriniz var mı? Yukarıdakileri denedim Receive-Job 3, ama hiçbir şey olmuyor.
not2qubit

@ not2qubit " konsol işleri" ile ne demek istediğinizden emin değilim . Arka planda çalıştırmak istediğiniz hangi komutu çalıştırıyorsunuz?
Mariusz Pawelski

Windows konsolunu başlatan bir uygulama kullanıyordum, ancak herhangi bir çıktı alamıyorum ve * ön planına iş getirmek için nix dünyasınafg benzer şekilde almayı umuyordum .
not2qubit

@ not2qubit Ne yazık ki powershell'de unix'e benzeyen bir şey yok gibi görünüyor fg:( Aradığımı hatırlıyorum, ancak hiçbir şey bulamadım
Mariusz Pawelski

17

Hedeflerinize ulaşmak için PowerShell iş cmdlet'lerini kullanabilirsiniz.

PowerShell'de işle ilgili 6 cmdlet vardır.

  • İş bul
    • Geçerli oturumda çalışan Windows PowerShell arka plan işlerini alır
  • Alma-İş
    • Geçerli oturumdaki Windows PowerShell arka plan işlerinin sonuçlarını alır
  • Kaldır-İş
    • Windows PowerShell arka plan işini siler
  • Start-İş
    • Windows PowerShell arka plan işini başlatır
  • Durdurma-İş
    • Windows PowerShell arka plan işini durdurur
  • Bekle-İş
    • Oturumda çalışan Windows PowerShell arka plan işlerinden biri veya tümü tamamlanıncaya kadar komut istemini bastırır

Bu konuda ilginçseniz, PowerShell'de arka plan işi nasıl oluşturulur örneğini indirebilirsiniz


1
Powershell 3+ ile uğraşırken iyi cevap. İş cmdlet'leri ile önceki yanıtlar arasındaki fark nedir?
Jeremy Hajek

3

Böyle bir şey yapabilirsiniz.

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

Ve beklemek isterseniz:

$a | wait-process

Bonus osx veya linux versiyonu:

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

Örnek pinger betiğim var. Bağımsız değişkenler bir dizi olarak iletilir:

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

start işlemi çatallar ve kontrolü arayana geri gönderir. Daha fazla bilgi burada
Aethalides

@Aethalides start aslında powershell'de başlatma işlemi için bir takma addır.
js2010


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.