2012-05-10 8 views
8

मैं एक साधारण समारोह निर्देशिकाओं के लिए जाँच करने के लिए लिखा है अंत में लिखा है के रूप मेंमैं फ़ंक्शन के भीतर से बैच फ़ाइल से कैसे बाहर निकल सकता हूं?</p> <pre><code>:direxist if not exist %~1 ( echo %~1 could not be found, check to make sure your location is correct. goto:end ) else ( echo %~1 is a real directory goto:eof ) </code></pre> <p>:

:end 
endlocal 

मुझे समझ नहीं आता क्यों कार्यक्रम गोटो के बाद बंद नहीं होगा: अंत बुलाया गया है । मेरे पास एक और कार्य है जो प्रोग्राम को रोकने के लिए एक ही विधि का उपयोग करता है और यह ठीक काम करता है।

:PRINT_USAGE 
echo Usage: 
echo ------ 
echo <file usage information> 
goto:end 

इस उदाहरण में, प्रोग्राम कॉलिंग के बाद बंद हो गया है: अंत; यह क्यों काम नहीं करेगा: direxist? आपके सहयोग के लिए धन्यवाद!

+0

संभव डुप्लिकेट http://stackoverflow.com/questions/3227796/exit-batch-script- अंदरूनी-ए-फ़ंक्शन) – Nathan

उत्तर

12

मैं तुम्हें यहाँ call और goto बयान मिश्रण कर रहे हैं लगता है।

बैच फ़ाइल में एक लेबल का उपयोग call या goto के साथ किया जा सकता है, लेकिन व्यवहार अलग है।
यदि आप call इस तरह के एक समारोह यह वापस आ जाएगी जब समारोह फ़ाइल के अंत या एक स्पष्ट exit /b या goto :eof (अपने goto :end की तरह) पर पहुंच गया।

इसलिए यदि आप फ़ंक्शन के रूप में लेबल का उपयोग करते हैं तो आप अपने बैच को रद्द नहीं कर सकते हैं।

हालांकि, goto एक लेबल में, कॉलर को वापस नहीं करेगा।

लेकिन फ़ंक्शन से बैच से बाहर निकलने का एक तरीका भी है।
आप एक वाक्यविन्यास त्रुटि बना सकते हैं, यह बैच को रोकने के लिए मजबूर करता है।

@echo off 
call :label hello 
call :label stop 
echo Never returns 
exit /b 

:label 
echo %1 
if "%1"=="stop" goto :halt 
exit /b 

:halt 
call :haltHelper 2> nul 

:haltHelper 
() 
exit /b 
+3

कॉलिंग बैच स्क्रिप्ट पर वापस आने में असमर्थता के अलावा, यह समाधान बैच समाप्ति पर होने वाली अनुमानित अंतःविषय को भी रोकता है, जिसके परिणामस्वरूप अवांछित लिंगरिंग एन्विन्रोनमेंट परिवर्तन होते हैं। – dbenham

+0

http://stackoverflow.com/a/25474648/1012053 देखें कि एक कॉलेड दिनचर्या से बैच प्रोसेसिंग से बाहर निकलने के लिए एक स्वच्छ तकनीक के लिए जो SETLOCAL को ठीक से समाप्त करता है। – dbenham

5

जेब का समाधान बहुत अच्छा काम करता है। लेकिन यह सभी परिस्थितियों में उचित नहीं हो सकता है।

1) सिंटैक्स त्रुटि सभी बैच प्रोसेसिंग रुक जाएगा: यह 2 संभावित कमियां हैं। तो यदि आपकी बैच नामक एक बैच स्क्रिप्ट है, और आपकी स्क्रिप्ट को वाक्यविन्यास त्रुटि से रोक दिया गया है, तो कॉलर को नियंत्रण वापस नहीं किया जाता है। यह बुरा हो सकता है।

2) आम तौर पर वहाँ हर SETLOCAL जब बैच प्रोसेसिंग समाप्त हो जाता है के लिए एक अंतर्निहित ENDLOCAL है। लेकिन घातक सिंटेक्स त्रुटि बैच प्रोसेसिंग समाप्त हो जाता है निहित ENDLOCAL बिना! यह बुरा परिणाम :-(मेरे DosTips अधिक जानकारी के लिए पोस्ट SETLOCAL continues after batch termination! देखें 2015-03-20एक साफ रास्ता तुरंत सभी बैच प्रोसेसिंग को समाप्त करने के लिए https://stackoverflow.com/a/25474648/1012053 देखें हो सकता है।

अद्यतन।

किसी फ़ंक्शन के भीतर बैच फ़ाइल को रोकने का दूसरा तरीका EXIT कमांड का उपयोग करना है, जो पूरी तरह से कमांड खोल से बाहर निकल जाएगा। लेकिन सीएमडी का थोड़ा रचनात्मक उपयोग समस्या को हल करने के लिए इसे उपयोगी बना सकता है।

@echo off 
if "%~1" equ "_GO_" goto :main 
cmd /c ^""%~f0" _GO_ %*^" 
exit /b 

:main 
call :label hello 
call :label stop 
echo Never returns 
exit /b 

:label 
echo %1 
if "%1"=="stop" exit 
exit /b 

मैं अपने दोनों संस्करण "daveExit.bat" नाम और जेब के संस्करण मेरी पीसी पर "jebExit.bat" नाम मिल गया है।

मैं तो उन्हें इस बैच स्क्रिप्ट

@echo off 
echo before calling %1 
call %1 
echo returned from %1 

मदद से इसका परीक्षण और यहाँ परिणामों से बाहर निकलने समाधान के

>test jebExit 
before calling jebExit 
hello 
stop 

>test daveExit 
before calling daveExit 
hello 
stop 
returned from daveExit 

> 

एक संभावित नुकसान यह है कि पर्यावरण में परिवर्तन संरक्षित नहीं किया जाता है। यही कारण है कि आंशिक रूप से बाहर निकलने से पहले एक अस्थायी फ़ाइल के लिए environent लेखन, और उसके बाद में इसे पढ़ने के वापस करके हल किया जा सकता है।

@echo off 
if "%~1" equ "_GO_" goto :main 
cmd /c ^""%~f0" _GO_ %*^" 
for /f "eol== delims=" %%A in (env.tmp) do set %%A 
del env.tmp 
exit /b 

:main 
call :label hello 
set junk=saved 
call :label stop 
echo Never returns 
exit /b 

:label 
echo %1 
if "%1"=="stop" goto :saveEnvAndExit 
exit /b 

:saveEnvAndExit 
set >env.tmp 
exit 

लेकिन मूल्य में न्यू लाइन चरित्र (0x0A) के साथ चर ठीक से संरक्षित नहीं किए जाएंगे।

+0

+1, यह भी अच्छा है, और आपके पास लाभ है कि अस्थायी चर हटा दिए गए हैं – jeb

+0

@jeb - मैं सोच रहा था कि पर्यावरण परिवर्तनीय सेटिंग्स का नुकसान एक नुकसान हो सकता है। लेकिन मैं आपकी बात देखता हूँ। बाहर निकलने की स्थिति से पहले किसी भी प्रकार की अस्थायी चर सेटिंग्स हो सकती हैं जिन्हें संरक्षित नहीं किया जाना चाहिए। यदि कोई चर है जिसे संरक्षित किया जाना चाहिए, तो उन्हें चुनिंदा रूप से एक अस्थायी फ़ाइल में लिखा जा सकता है और सीएमडी लौटने पर बहाल किया जा सकता है। – dbenham

1

यहाँ मेरी समाधान है कि नेस्टेड दिनचर्या का समर्थन करेंगे, तो सब मैं अपने सभी कॉल (आंतरिक या बाह्य)

@echo off 
call :error message&if errorlevel 1 exit /b %errorlevel%< 
@echo continuing 
exit /b 0 
:error 
@echo in %0 
@echo message: %1 
set yes= 
set /p yes=[no]^|yes to continue 
if /i "%yes%" == "yes" exit /b 0 
exit /b 1 
+0

मैंने आपकी पोस्ट से कुछ नया सीखा। % 0 की गूंज कुछ ऐसा है जो मैं कभी नहीं (एक फ़ंक्शन के लिए)। धन्यवाद! – djangofan

1

आप exit /b X का उपयोग करते हैं समारोह से बाहर निकलने के लिए कम से errolevel के लिए परीक्षण जोड़ने errorlevel लिए जाँच की जाती है तो यह के मान पर ERRORLEVEL सेट करेगा। ERRORLEVEL शून्य शून्य होने पर आप कमांड निष्पादित करने के लिए ||conditional processing symbol का उपयोग कर सकते हैं। इस स्क्रिप्ट से

@echo off 
setlocal 
call :myfunction PASS || goto :eof 
call :myfunction FAIL || goto :eof 
echo Execution never gets here 
goto :eof 

:myfunction 
    if "%1"=="FAIL" ( 
     echo myfunction: got a FAIL. Will exit. 
     exit /b 1 
    ) 
    echo myfunction: Everything is good. 
    exit /b 0 

आउटपुट है:

myfunction: Everything is good. 
myfunction: got a FAIL. Will exit. 
[एक समारोह के अंदर से बाहर निकलें बैच स्क्रिप्ट] (की
संबंधित मुद्दे

 संबंधित मुद्दे