अगली बार शुरू करने से पहले प्रत्येक कमांड के समाप्त होने की प्रतीक्षा करने के लिए पॉवरशेल को कैसे बताएं?


212

मेरे पास अनुप्रयोगों का एक गुच्छा खोलने के लिए एक PowerShell 1.0 स्क्रिप्ट है। पहली एक वर्चुअल मशीन है और अन्य विकास अनुप्रयोग हैं। मैं चाहता हूं कि बाकी अनुप्रयोगों के खुलने से पहले वर्चुअल मशीन बूटिंग खत्म कर दे।

बैश में मैं बस कह सकता था "cmd1 && cmd2"

यह मुझे मिल गया है ...

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

जवाबों:


367

आम तौर पर, आंतरिक आदेशों के लिए PowerShell अगली कमांड शुरू करने से पहले प्रतीक्षा करता है। इस नियम का एक अपवाद बाहरी Windows सबसिस्टम आधारित EXE है। पहली चाल पाइप लाइन को Out-Nullपसंद करने के लिए है:

Notepad.exe | Out-Null

PowerShell प्रतीक्षा करेगी जब तक कि Notepad.exe प्रक्रिया जारी रखने से पहले बाहर नहीं हो जाती। यह निफ्टी है लेकिन कोड पढ़ने से लेने के लिए सूक्ष्म है। आप स्टार्ट-प्रोसेस का उपयोग -Wit पैरामीटर के साथ भी कर सकते हैं:

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

यदि आप PowerShell सामुदायिक एक्सटेंशन संस्करण का उपयोग कर रहे हैं, तो यह है:

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

PowerShell 2.0 में एक अन्य विकल्प पृष्ठभूमि नौकरी का उपयोग करना है:

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

2
मेरी गलती। Start-Process -Wit बहुत अच्छा काम करता है, लेकिन अब मैं इसे देखता हूं कि यह वह नहीं है जिसकी मुझे तलाश थी ... मैं वास्तव में vm को बूटिंग खत्म होने तक इंतजार करना चाहता हूं। मुझे लगता है कि यह कठिन होने जा रहा है। मुझे लगता है कि मुझे उसके लिए एक नया सूत्र ढूंढना होगा। धन्यवाद लेकिन।
जॉन एमई

7
शानदार, | out-nullबस वही किया जो मुझे चाहिए था। का उपयोग करने की कोशिश की, Start-Jobलेकिन क्योंकि मैं मापदंडों के रूप में कार्यों के परिणामों को पारित कर रहा हूँ, यह मुझ पर एक छोटा सा skitzoid मिला, इसलिए मैं अंतिम सुझाव का उपयोग नहीं कर सका ...
jcolebrand

6
एक साइड नोट के रूप में, यदि आपको कई तर्कों को पारित करने की आवश्यकता है, तो -ArgumentListउन्हें अल्पविराम से अलग करें -ArgumentList /D=test,/S
sschuberth

1
सरल "<ex करने के लिए पथ> | आउट-नल" समाधान के लिए धन्यवाद! "स्टार्ट-प्रोसेस <मार्ग को exe> -NoNewWindow -Wait" विधि के साथ समस्या यह है कि PowerShell तब तक रुकता है जब तक कि माता-पिता द्वारा पैदा की गई सभी बच्चे की प्रक्रिया पूरी नहीं हो जाती है, भले ही माता-पिता उनके सामने समाप्त हो जाएं। इससे हमारे सेटअप प्रोग्राम की समस्याएँ हुईं।
zax

यह वह है जो मैं एक वीएम के शुरू होने के लिए प्रतीक्षा करने के लिए उपयोग करता हूं। _.कोड -मैच "पॉवरस्टेट"}। दूरस्थ अनुरोध
andrewmo

47

उपयोग करने के अलावा Start-Process -Wait, एक निष्पादन योग्य के उत्पादन को पाइप करने से पॉवर्सशेल प्रतीक्षा होगी। आवश्यकतानुसार, मैं करूँगा आम तौर पर पाइप के लिए Out-Null, Out-Default, Out-Stringया Out-String -Streamयहां कुछ अन्य आउटपुट विकल्पों की एक लंबी सूची दी गई है।

# 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

मुझे सीएमडी / बैश शैली के ऑपरेटरों की याद आती है जिन्हें आपने संदर्भित किया था (&, &&, ||)। ऐसा लगता है कि हमें पॉवरशेल के साथ और अधिक क्रिया करनी होगी ।


यह एक अविश्वसनीय रूप से अच्छा समाधान है यदि आपको आउटपुट पार्स करने की आवश्यकता है!
जन रोथकेगल

आउट-एक्सएक्सएक्स रीडायरेक्टर्स सूची को इंगित करने से मुझे जल्दी से यह समझने की अनुमति मिली कि मुझे आउट-नल के बजाय आउट-डिफॉल्ट का उपयोग क्यों करना चाहिए , क्योंकि मुझे कंसोल आउटपुट रखने की आवश्यकता थी।
जूलियो नोब्रे

ध्यान दें कि सांत्वना अनुप्रयोगों को समकालिक रूप से निष्पादित करने के लिए किसी अतिरिक्त कार्य की आवश्यकता नहीं है - जैसा कि किसी भी शेल में है, जो कि डिफ़ॉल्ट व्यवहार है। करने के लिए पाइप परिवर्तन उत्पादन एक करने के लिए एक, बहु लाइन स्ट्रिंग डिफ़ॉल्ट रिटर्न से एक है, जबकि PowerShell लाइनों की सरणी । कंसोल एप्लिकेशन के लिए टाला जाना चाहिए (जब तक कि आप वास्तव में उन्हें एक नई विंडो में नहीं चलाना चाहते ) क्योंकि आप उनके आउटपुट को कैप्चर या रीडायरेक्ट नहीं कर पाएंगे। Out-String Start-Process
mklement0

वास्तव में, चाहे एक देशी कमांड सिंक्रोनाइज़ (आउटपुट के साथ) या असिंक्रोनस रूप से निष्पादन योग्य पर निर्भर करता है। एक उदाहरण के रूप में, आउटपुट को कैप्चर किए बिना, निम्नलिखित केवल "बिंगो" आउटपुट करता है। & 'C: \ Program Files \ Mozilla Firefox \ firefox.exe' -? ; 'बिंगो'
नाथन हार्टले

12

बस "प्रतीक्षा-प्रक्रिया" का उपयोग करें:

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

नौकरी हो गई


8

यदि तुम प्रयोग करते हो Start-Process <path to exe> -NoNewWindow -Wait

आप -PassThruआउटपुट को इको करने के लिए विकल्प का भी उपयोग कर सकते हैं ।


ध्यान दें कि आउटपुट-PassThru प्रतिध्वनित नहीं करता है (परिभाषा द्वारा एक गैर-कंसोल-एप्लिकेशन कंसोल आउटपुट का उत्पादन नहीं करेगा), यह एक ऐसे उदाहरण को आउटपुट करता है जो नई लॉन्च की गई प्रक्रिया का प्रतिनिधित्व करता है, इसलिए आप इसके गुणों की जांच कर सकते हैं और बाद में बाहर निकलने के लिए इंतजार कर सकते हैं। System.Diagnostics.Process
mklement0

6

कुछ प्रोग्राम आउटपुट स्ट्रीम को बहुत अच्छी तरह से प्रोसेस नहीं कर सकते हैं, पाइप का इस्तेमाल Out-Nullइसे ब्लॉक नहीं कर सकता है।
और तर्कों को पारित Start-Processकरने के लिए -ArgumentListस्विच की आवश्यकता है, इतना सुविधाजनक नहीं है।
एक और दृष्टिकोण भी है।

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

1
उस कॉल में कितने तर्क काम करते हैं? वे कैसे सीमांकित हैं? कैसे विभिन्न नेस्टेड स्ट्रिंग से बच निकलता है? Ty!
ऐनीएजिले

1
@AnneTheAgile डॉक उपयोग अंतरिक्ष तर्क अलग करने के लिए चार से बचने के उपयोग बैकस्लैश के लिए,
iFree

ty @ifree, मुझे इस तरह से चलाने के लिए गवाही मिली! मैंने अंतरिक्ष सीमांकित तर्कों की सूची के आसपास एकल उद्धरणों का उपयोग किया। [१]; लेकिन अब गूंज $ एक्स्टोडकोड = गलत है, जो इस प्रक्रिया से मेरा रिटर्नकोड नहीं था? [१] $ एक्जिटकोड = [डायग्नोस्टिक्स.प्रोसेस] :: प्रारंभ ("c: \ Program Files (x86) \ SmartBear \ TestComplete 10 \ Bin \ TestComplete.exe", "" c: \ Users \ ME के ​​दस्तावेज़ \ _ परीक्षण १० प्रोजेक्ट्स \ hig4TestProject1 \ hig4TestProject1.pjs "/ run / Project: myProj / test:" KeywordTests | zTdd1_Good "/ exit ') .WaForForExit (60)
AnneTheAgile

3

विकल्प सहित -NoNewWindowमुझे एक त्रुटि देता है:Start-Process : This command cannot be executed due to the error: Access is denied.

मुझे काम करने का एकमात्र तरीका यह मिल सकता था:

Start-Process <path to exe> -Wait

0

इसे और आगे ले जाने पर आप मक्खी पर भी जा सकते हैं

जैसे

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

0

वहाँ हमेशा cmd है। यदि आपको प्रक्रिया शुरू करने के लिए तर्क देने में परेशानी हो तो यह कम कष्टप्रद हो सकता है:

cmd /c start /wait notepad
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.