PowerShell'e bir sonraki başlamadan önce her komutun bitmesini beklemesini nasıl söyleyebilirim?


212

Sadece bir grup uygulamaları açmak için bir PowerShell 1.0 betiği var. Birincisi sanal bir makine, diğerleri ise geliştirme uygulamaları. Diğer uygulamalar açılmadan önce sanal makinenin önyüklemeyi bitirmesini istiyorum.

Bash'da diyebilirim ki "cmd1 && cmd2"

Elimde olan bu ...

C:\Applications\VirtualBox\vboxmanage startvm superdooper
    &"C:\Applications\NetBeans 6.5\bin\netbeans.exe"

Yanıtlar:


367

Normal olarak, dahili komutlar için PowerShell bir sonraki komutu başlatmadan önce bekler. Bu kuralın bir istisnası harici Windows alt sistemi tabanlı EXE'dir. İlk hile bu şekilde boru hattı yapmaktır Out-Null:

Notepad.exe | Out-Null

PowerShell, devam etmeden önce Notepad.exe işleminden çıkana kadar bekleyecektir. Bu şık ama kodu okumak için bir tür ince. Start-Process'i -Wait parametresiyle de kullanabilirsiniz:

Start-Process <path to exe> -NoNewWindow -Wait

PowerShell Topluluk Uzantıları sürümünü kullanıyorsanız:

$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()

PowerShell 2.0'daki başka bir seçenek de arka plan işi kullanmaktır:

$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job

2
Benim hatam. Start-Process -Wait harika çalışıyor, ama şimdi görüyorum bu aradığım şey değil ... Aslında vm önyüklemeyi bitirmek için beklemek için arıyorum. Bunun zor olacağını hayal ediyorum. Sanırım bunun için yeni bir konu bulmam gerekecek. Teşekkürler fakat.
John Mee

7
Parlak, | out-nulltam ihtiyacım olan şeyi yaptım. Kullanmayı denedim Start-Jobama fonksiyonların sonuçlarını parametre olarak geçirdiğim için üzerimde biraz skitzoid var, bu yüzden son öneriyi kullanamadım ...
jcolebrand

6
Yan not olarak, ile birden fazla argüman iletmeniz gerekiyorsa -ArgumentList, bunları virgül gibi ayırın -ArgumentList /D=test,/S.
sschuberth

1
Basit "<exe yolu> | Out-Null" çözümü için teşekkür ederiz! "Başlat-İşlem <exe yolu> -NoNewWindow -Wait" yöntemi ile ilgili sorun, üst tarafından üretilen son alt işlemler tamamlanana kadar PowerShell duraklatılır. Bu, kurulum programı sorunlarımıza neden oldu.
zax

Bu, bir VM'nin Start-AzureRmVM -ResourceGroupName $ ResourceGroupName -Name $ VmName ((Get-AzureRmVM -ResourceGroupName $ ResourceGroupName -Name $ VmName -Status | `select -ExpandProperty Statuses | $ {? {{ _.Code -match "PowerState"} | `select -ExpandProperty DisplayStatus) -ne" VM çalışıyor ") {Start-Sleep -s 2} Start-Sleep -s 5 ## VM'ye kabul etmesi için zaman tanıyın uzak istekleri
andrewmo

47

Kullanmanın yanı sıra Start-Process -Wait, bir yürütülebilir dosyanın çıkışının borulanması Powershell'i bekletir. İhtiyaca bağlı olarak, ben genellikle boru için olacak Out-Null, Out-Default, Out-Stringveya Out-String -Stream. İşte bazı diğer çıktı seçeneklerini uzun listesidir.

# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String

# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }

# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com

Başvurduğunuz CMD / Bash stil operatörlerini (&, &&, ||) özledim. Görünüşe göre Powershell ile daha ayrıntılı olmalıyız .


Çıktıyı ayrıştırmanız gerekiyorsa, bu inanılmaz derecede iyi bir çözümdür!
Jan Rothkegel

Out-xxxx yeniden yönlendiricileri listesini işaret etmek, konsol çıktısını tutmam gerektiğinden neden Out-Null yerine Out-Default kullanmam gerektiğini anlamamı sağladı .
Julio Nobre

Konsol uygulamalarını eşzamanlı olarak yürütmek için fazladan bir çalışmaya gerek olmadığını unutmayın - herhangi bir kabukta olduğu gibi, bu varsayılan davranıştır. Boru tesisatı değişiklikler çıkış a tek, çok hatlı değerini döndürür PowerShell ise, bir dizeye hatlarının dizisi . konsol uygulamalarında (gerçekten yeni bir pencerede gerçekten çalıştırmak istemiyorsanız) kaçınılmalıdır çünkü çıktılarını yakalayamaz veya yönlendiremezsiniz. Out-String Start-Process
mklement0

Aslında, yerel bir komutun eşzamanlı (çıktı ile) veya eşzamansız olarak çalıştırılabilir olması yürütülebilir dosyaya bağlıdır. Örnek olarak, çıktı yakalanmadan aşağıdakiler yalnızca "bingo" çıktısı verir. & 'C: \ Program Dosyaları \ Mozilla Firefox \ firefox.exe' -? ; 'bingo'
Nathan Hartley

12

Sadece "Bekleme-işlemi" kullanın:

"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir

iş tamam


8

Eğer kullanırsan Start-Process <path to exe> -NoNewWindow -Wait

-PassThruÇıktıyı yankılamak için bu seçeneği de kullanabilirsiniz .


Çıktıyı-PassThru yankılamadığını unutmayın (tanım gereği konsol dışı bir uygulama konsol çıktısı üretmez), yeni başlatılan işlemi temsil eden bir örnek çıktılar , böylece özelliklerini inceleyebilir ve daha sonra çıkmasını bekleyebilirsiniz. System.Diagnostics.Process
mklement0

6

Bazı programlar çıkış akışını çok iyi işleyemez, Out-Nullengellemek için pipe kullanarak .
Ve çok uygun değil, argümanları geçmek için geçişe Start-Processihtiyacı var -ArgumentList.
Başka bir yaklaşım daha var.

$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)

1
bu çağrıda birden çok argüman nasıl çalışır? nasıl sınırlandırılırlar? nasıl kaçan çeşitli iç içe dize ele? ty!
AnneTheAgile

1
@AnneTheAgile doc , bağımsız değişkenleri ayırmak için boşluk kullanır, karakterden kaçmak için ters eğik çizgi kullanın
ifree

ty @ ifree, bu şekilde çalıştırmak için test tamamladım! Alan sınırlı argümanlar listesinde tek tırnak kullandım. [1]; ama şimdi echo $ exitcode = false, işlemdeki dönüş kodum hangisi değildi? [1] $ exitCode = [Diagnostics.Process] :: Başlat ("c: \ Program Dosyaları (x86) \ SmartBear \ TestComplete 10 \ Bin \ TestComplete.exe", '"c: \ Kullanıcılar \ ME \ Belgeler \ TestComplete 10 Projeler \ hig4TestProject1 \ hig4TestProject1.pjs "/ run / project: myProj / test:" KeywordTests | zTdd1_Good "/ exit ') .WaitForExit (60)
AnneTheAgile

3

Seçeneği dahil etmek -NoNewWindowbana bir hata veriyor:Start-Process : This command cannot be executed due to the error: Access is denied.

Ben işe almak için tek yolu aramak oldu:

Start-Process <path to exe> -Wait

0

Daha da ileri götürürken anında bile ayrıştırabilirsiniz

Örneğin

& "my.exe" | %{
    if ($_ -match 'OK')
    { Write-Host $_ -f Green }
    else if ($_ -match 'FAIL|ERROR')
    { Write-Host $_ -f Red }
    else 
    { Write-Host $_ }
}

0

Her zaman cmd vardır. Başlangıç ​​işlemine yönelik bağımsız değişkenleri alıntılamakta sorun yaşıyorsanız daha az can sıkıcı olabilir:

cmd /c start /wait notepad
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.