PowerShell में स्क्रिप्ट को समाप्त करना


394

जब किसी फ़ंक्शन में कोई अपरिवर्तनीय त्रुटि होती है, तो मैं PowerShell (PS1) स्क्रिप्ट को समाप्त करने का तरीका ढूंढ रहा हूं। उदाहरण के लिए:

function foo() {
    # Do stuff that causes an error
    $host.Exit()
}

बेशक ऐसी कोई बात नहीं है $host.Exit()। वहाँ है $host.SetShouldExit(), लेकिन यह वास्तव में कंसोल विंडो को बंद कर देता है, जो कि मैं नहीं चाहता। मुझे पाइथन के समतुल्य कुछ और चाहिए sys.exit()जो आगे की परिधि के बिना वर्तमान स्क्रिप्ट के निष्पादन को रोक देगा।

संपादित करें: हाँ, यह सिर्फ है exit। ओह।


8
यदि आप मेरे मामले में PowerShell विंडो या ISE को बंद करने से बचना चाहते हैं; इसके बजाय "वापसी" का उपयोग करें। यह बस चालू चल रहे संदर्भ को समाप्त करता है। "नया आदमी" शैक्षिक उद्देश्यों के लिए सभी विकल्पों को अच्छी तरह से समझाता है; आप भविष्य के StackOverflow उपयोगकर्ताओं के लिए अपने स्वीकृत उत्तर (वर्तमान में और अधिक वोट वैसे भी) को बदलने पर विचार कर सकते हैं। यह आपको स्क्रिप्ट को डीबग करने की अनुमति देगा।
ZaxLofful

क्या इससे आपके सवाल का जवाब मिलता है? PowerShell में वास्तव में "निकास" क्या है?
मार्क शुल्त्स

जवाबों:


389

आप का उपयोग करना चाहिए कीवर्डexit


15
पवित्र बकवास, अगर मैं इतना समझ नहीं पाया कि कैसे इन चीजों को चतुराई से करने की कोशिश करूं तो मैंने शायद कोशिश की होगी कि इसके साथ शुरू करने और यह पता लगाने की कोशिश करें :) धन्यवाद।

118
यह स्वीकृत उत्तर कैसे है? यह विशेष रूप से "कंसोल विंडो को बंद करता है" जिसे पूछने वाले ने कहा "जो मैं चाहता हूं वह नहीं है।"
क्लुडेकेनिलोल

3
@claudekennilol केवल प्रश्न पूछने वाला ही उत्तर स्वीकार कर सकता है। या तो उन्होंने इस तथ्य को याद किया कि निकास खिड़की को बंद करना है, या उन्होंने अपना मन बदल दिया और अपने उद्देश्य के लिए स्वीकार्य माना।
इस्ति

3
यह v3 या v4 में कंसोल विंडो को बंद नहीं करता है, जिसका मैं उपयोग करता हूं। खैर, यह होगा यदि आप स्क्रिप्ट को एक्सप्लोरर से चलाते हैं, लेकिन कोई फर्क नहीं पड़ता कि आप स्क्रिप्ट को कैसे समाप्त करते हैं। यदि PowerShell कमांड विंडो से चल रहा है तो यह विंडो को बंद नहीं करता है।
जोशुआ Nurczyk 7

14
न्यू गाइ द्वारा उत्तर को अधिक अच्छी तरह से और deservers के रूप में चिह्नित किया जा रहा है।
जिम अहो

585

मुझे लगता है कि यह एक पुरानी पोस्ट है, लेकिन मैं इस विषय पर खोज करते समय अपने आप को इस थ्रेड पर वापस आता हूं क्योंकि यह शीर्ष खोज परिणामों में से एक है। हालांकि, मैं हमेशा अधिक उलझन में छोड़ देता हूं तब जब मैं परस्पर विरोधी सूचनाओं के कारण आया था। अंततः मुझे हमेशा यह पता लगाने के लिए अपने परीक्षण करने पड़ते हैं। इसलिए इस बार मैं अपने निष्कर्षों को पोस्ट करूंगा।

टीएल; डीआर अधिकांश लोग Exitएक रनिंग स्क्रिप्ट को समाप्त करने के लिए उपयोग करना चाहेंगे । हालाँकि, यदि आपकी स्क्रिप्ट केवल बाद में उपयोग किए जाने वाले फ़ंक्शन की घोषणा कर रही है, तो आप Returnउक्त फ़ंक्शन की परिभाषाओं में उपयोग करना चाहेंगे ।

रिटर्न बनाम ब्रेक से बाहर निकलें

  • बाहर निकलें: यह वर्तमान में चल रहे संदर्भ को "बाहर" कर देगा। यदि आप इस कमांड को स्क्रिप्ट से कहते हैं तो यह स्क्रिप्ट से बाहर निकल जाएगा। यदि आप शेल से इस कमांड को कॉल करते हैं तो यह शेल से बाहर निकल जाएगा।

    यदि कोई फ़ंक्शन एक्ज़िट कमांड को कॉल करता है तो यह बाहर निकल जाएगा कि यह किस संदर्भ में चल रहा है। इसलिए यदि उस फ़ंक्शन को केवल एक रनिंग स्क्रिप्ट के भीतर से बुलाया जाता है तो वह उस स्क्रिप्ट से बाहर निकल जाएगा। हालाँकि, यदि आपकी स्क्रिप्ट केवल फ़ंक्शन की घोषणा करती है, ताकि इसका उपयोग वर्तमान शेल से किया जा सके और आप शेल से उस फ़ंक्शन को चलाते हैं, तो यह शेल से बाहर निकल जाएगा क्योंकि शेल वह संदर्भ है जिसमें Exitकमांड को चलाने वाला फ़ंक्शन चल रहा है।

    नोट: डिफ़ॉल्ट रूप से यदि आप राइट को पावरस्ले में चलाने के लिए स्क्रिप्ट पर क्लिक करते हैं, तो स्क्रिप्ट चलने के बाद, पावरशेल स्वतः बंद हो जाएगा। इसका Exitआपकी स्क्रिप्ट में कमांड या किसी और चीज से कोई लेना-देना नहीं है । स्क्रिप्ट चलाने की इस विशिष्ट विधि का उपयोग करके स्क्रिप्ट चलाने के लिए यह केवल एक डिफ़ॉल्ट PowerShell व्यवहार है। बैच फ़ाइलों और कमांड लाइन विंडो के लिए भी यही सच है।

  • वापसी: यह पिछले कॉल बिंदु पर वापस आ जाएगा। यदि आप इस कमांड को किसी स्क्रिप्ट (किसी फ़ंक्शन के बाहर) से कॉल करते हैं तो यह शेल पर वापस आ जाएगी। यदि आप शेल से इस कमांड को कॉल करते हैं तो यह शेल पर वापस आ जाएगा (जो शेल से चलाए गए सिंगल कमांड के लिए पिछला कॉल पॉइंट है)। यदि आप इस कमांड को किसी फंक्शन से बुलाते हैं, तो यह वहीं पर वापस आएगा जहाँ से फंक्शन को कॉल किया गया था।

    कॉल बिंदु के बाद किसी भी कमांड का निष्पादन जो इसे वापस किया जाता है, उस बिंदु से जारी रहेगा। यदि किसी स्क्रिप्ट को शेल से कॉल किया जाता है और इसमें Returnकिसी भी फ़ंक्शन के बाहर कमांड होती है, तो जब वह शेल पर लौटता है तो चलाने के लिए अधिक कमांड नहीं होते हैं और Returnइस तरह से उपयोग किया जाता है अनिवार्य रूप से उसी तरह से Exit

  • ब्रेक: यह लूप से बाहर निकल जाएगा और मामलों को स्विच करेगा। यदि आप इस आदेश को लूप या स्विच केस में नहीं कहते हैं तो यह स्क्रिप्ट से बाहर हो जाएगा। यदि आप Breakएक लूप के अंदर कॉल करते हैं जो एक लूप के अंदर नेस्टेड है तो यह केवल उस लूप से बाहर निकलेगा जिसे इसे अंदर बुलाया गया था।

    एक दिलचस्प विशेषता यह भी है Breakकि आप एक लेबल के साथ लूप को कैसे उपसर्ग कर सकते हैं और फिर आप उस लेबल वाले लूप से बाहर निकल सकते हैं, भले ही Breakकमांड को उस लेबल वाले लूप के भीतर कई नेस्टेड समूहों के भीतर बुलाया जाए।

    While ($true) {
        # Code here will run
    
        :myLabel While ($true) {
            # Code here will run
    
            While ($true) {
                # Code here will run
    
                While ($true) {
                    # Code here will run
                    Break myLabel
                    # Code here will not run
                }
    
                # Code here will not run
            }
    
            # Code here will not run
        }
    
        # Code here will run
    }

39
यह भी ध्यान देने योग्य है कि Exitएक रिटर्न कोड को एक पैरामीटर के रूप में लिया जा सकता है (चूक 0 से) - जैसे Exit 3
Aucuparia

2
मैं सहमत हूं, यह एक बेहतर जवाब है। "ब्रेक" के अनपेक्षित परिणाम हो सकते हैं।
इगोमार्टिनेज़

मुझे यकीन नहीं है कि "बाहर निकलें" के बारे में आपकी टिप्पणी पूरी तरह से सही है, हालांकि यह समग्र रूप से एक महान जवाब है। ऐसा लगता है कि ISE को इस तरह से बंद करने का कारण बन रहा है कि ऐसा कुछ नहीं हो रहा है। बस संदर्भ से बाहर निकलें (उदाहरण के लिए, स्क्रिप्ट पूरा करना) ऐसा नहीं करता है।
बिल के

1
@ बिलक वास्तव। मैंने जवाब अपडेट कर दिया है। जब मैंने पहली बार यह लिखा था तो मुझे याद आया कि मुझे बाहर निकलने पर कोई आधिकारिक दस्तावेज नहीं मिला था। मैं तो एक Get-Command Exitऔर Get-Alias Exitकोई परिणाम के साथ किया था । मैंने तब देखा कि क्या यह एक कीवर्ड था और इस पर कोई आधिकारिक दस्तावेज नहीं मिला। हालांकि इसे देखते हुए, मुझे नहीं पता कि मैं उस नतीजे पर कैसे आया। स्पष्ट रूप से यह एक कीवर्ड है ( Technet.microsoft.com/en-us/library/hh847744.aspx )। शायद इसलिए कि एग्जिट एकमात्र ऐसा कीवर्ड है जिसके पास अपना स्वयं का_ विषय नहीं है और इसलिए बाएं साइडबार में विषयों की सूची में इसे शामिल किया गया है।
न्यू गाय

6
थ्रो के बारे में क्या?
जेडीसी

80

ExitPowerShell से भी बाहर निकल जाएगा। यदि आप केवल वर्तमान फ़ंक्शन या स्क्रिप्ट से "ब्रेक" करना चाहते हैं - उपयोग Break:)

If ($Breakout -eq $true)
{
     Write-Host "Break Out!"
     Break
}
ElseIf ($Breakout -eq $false)
{
     Write-Host "No Breakout for you!"
}
Else
{
    Write-Host "Breakout wasn't defined..."
}

5
कृपया breakतब उपयोग न करें जब वर्तमान फ़ंक्शन को तोड़ना चाहते हैं ... कॉलिंग स्क्रिप्ट को बाधित किया जा सकता है!
डैनीमिस्टर

49

लिखने की त्रुटि गैर-समाप्ति त्रुटियों के लिए है और फेंक त्रुटियों को समाप्त करने के लिए है

राइट-एरर cmdlet एक गैर-समाप्ति त्रुटि घोषित करता है। डिफ़ॉल्ट रूप से, त्रुटियों को आउटपुट के साथ प्रदर्शित होने वाले होस्ट प्रोग्राम में त्रुटि स्ट्रीम में भेजा जाता है।

नॉन-टर्मिनेटिंग एरर एरर स्ट्रीम में त्रुटि लिखते हैं, लेकिन वे कमांड प्रोसेसिंग को रोकते नहीं हैं। यदि इनपुट आइटमों के संग्रह में एक आइटम पर एक गैर-समाप्ति त्रुटि घोषित की जाती है, तो आदेश संग्रह में अन्य वस्तुओं को संसाधित करना जारी रखता है।

एक समाप्ति त्रुटि घोषित करने के लिए, थ्रो कीवर्ड का उपयोग करें। अधिक जानकारी के लिए, देखें_Throw ( http://go.microsoft.com/fwlink/?LinkID=145153 )।


4
किसी गतिविधि को किसी त्रुटि के साथ समाप्त करने का यह सबसे सही तरीका है। यह कॉल करने वाले को त्रुटि को संभालने का प्रयास करने के लिए सौंपता है, जो कि अचानक समाप्त करने के प्रयास से बहुत बेहतर है।
पॉल टर्नर

मेरे लिए, कम से कम मॉड्यूल फ़ंक्शंस में, एग्ज़िट फेंक दें, लेकिन एग्ज़िट कोड सेट न करें। यह सीएलआई जैसे के माध्यम से निष्पादित किया गया था powershell -command "& module-function ..."। मुझे उन कार्यों को एक रैपिंग ट्रिप-कैच में फेंकने और उस रैपिंग कैच से बाहर निकलने की आवश्यकता थी ताकि वास्तव में एक एरर एग्जिट कोड को आउटपुट किया जा सके।
जोश

2
$PSCmdlet.ThrowTerminatingError()उन उदाहरणों के लिए मत भूलना जब फेंकना बस काम नहीं कर सकता है (से कोई भी समाप्ति त्रुटियों के साथ ज्ञात समस्या throw)
Djarid

33

इस प्रक्रिया को समाप्त करता है और अंतर्निहित ऑपरेटिंग सिस्टम को निर्दिष्ट निकास कोड देता है।

https://msdn.microsoft.com/en-us/library/system.environment.exit%28v=vs.110%29.aspx

[Environment]::Exit(1)

यह आपको एक विशिष्ट निकास कोड के साथ बाहर निकलने की अनुमति देगा, जिसे कॉलर से उठाया जा सकता है।


3
PowerShell में, आप इसके लिए बिल्ट-इन एक्जिट का उपयोग कर सकते हैं, जैसे Exit 1
जोनास

3
बिल्ट-इन एग्जिट हमेशा आपकी अपेक्षा के अनुरूप काम नहीं करेगा। इसे पॉवरशेल में आज़माएं: "5 से बाहर निकलें"> test1.ps1 powerhell.exe। \ Test1.ps1 $ lastexitcode "[पर्यावरण] :: Exit (5)"> test2.ps1 powerhell.exe। \ Test2 .ps1 $ lastexitcode
gabriwinter।

1
[Environment]::Exit(1)जब मैं एक स्क्रिप्ट में exitऐसा करने के लिए प्रकट नहीं होता है, तो जब मैं इसे एक स्क्रिप्ट में आह्वान करता हूं, तो मेरी पावरशेल विंडो से बाहर निकलने का साइड इफेक्ट है ।
जोश डेसमंड

25

मुझे लगता है कि आप के Returnबजाय की तलाश कर रहे हैं Break। ब्रेक आमतौर पर छोरों के लिए उपयोग किया जाता है और केवल अंतर कोड ब्लॉक से टूटता है। किसी फ़ंक्शन या स्क्रिप्ट से बाहर निकलने के लिए रिटर्न का उपयोग करें।


7
यह सही नहीं है - ओपी विशेष रूप से एक फ़ंक्शन के भीतर से एक स्क्रिप्ट से बाहर निकलने के लिए कहता हैReturnकेवल फंक्शन से लौटेंगे, स्क्रिप्ट से नहीं। ( एक स्क्रिप्ट Returnके शीर्ष स्तर पर स्क्रिप्ट को समाप्त कर दिया जाएगा, लेकिन यह सवाल नहीं था।)
माइकल सोरेंस

1
क्या यह 'उत्तर' वास्तव में EverydayNerd उत्तर पर टिप्पणी थी?
टोंकसिह

22

अपवाद फेंकना अच्छा होगा, खासकर यदि आप त्रुटि कारण को स्पष्ट करना चाहते हैं:

throw "Error Message"

यह एक समाप्ति त्रुटि उत्पन्न करेगा।


3
मुझे नहीं लगता कि यह ग्रेग ब्रे के जवाब से लगभग एक साल पहले stackoverflow.com/a/20556550/695671
जेसन एस

12

हो सकता है कि "ट्रैप" का उपयोग करना बेहतर हो। PowerShell जाल किसी समाप्ति या त्रुटि के होने पर चलाने के लिए एक कोडब्लॉक निर्दिष्ट करता है। प्रकार

Get-Help about_trap

जाल विवरण के बारे में अधिक जानने के लिए।


10

मुझे संयोग से पता चला कि (उदाहरण के लिए , जहां लेबल मौजूद नहीं है ) पूरी स्क्रिप्ट (यहां तक ​​कि एक फ़ंक्शन के भीतर से) को तोड़ने के लिए प्रकट होता है और मेजबान को जीवित रखता है। इस तरह से आप एक ऐसा फंक्शन बना सकते हैं जो स्क्रिप्ट को कहीं से भी तोड़ सकता है (उदाहरण के लिए एक पुनरावर्ती लूप) जो कि मौजूदा स्कोप (और लेबल बनाने) के बिना नहीं है:Break <UnknownLabel>Break ScriptScript

Function Quit($Text) {
    Write-Host "Quiting because: " $Text
    Break Script
} 

1
आपका उत्तर सही है, लेकिन इस बात से अवगत
रहें

5

मैंने एक कार्यक्रम के पुनर्मिलन के लिए इसका उपयोग किया। मुझे नहीं पता कि यह मदद करेगा, लेकिन यह एक सरल है अगर बयान में केवल दो अलग-अलग प्रविष्टि की आवश्यकता होती है। इसने मेरे लिए शक्तियों में काम किया।

$rerun = Read-Host "Rerun report (y/n)?"

if($rerun -eq "y") { Show-MemoryReport }
if($rerun -eq "n") { Exit }

अगर यह मदद करता है पता नहीं है, लेकिन मेरा मानना ​​है कि आप इसे चलाने के बाद एक कार्यक्रम को समाप्त करने की तर्ज पर होगा। हालाँकि इस मामले में, हर परिभाषित इनपुट के लिए एक सूचीबद्ध और श्रेणीबद्ध आउटपुट की आवश्यकता होती है। आप एक नई प्रॉम्प्ट लाइन से बाहर निकल सकते हैं और इस तरह से कार्यक्रम को समाप्त कर सकते हैं।

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