क्या मेरे पास DOS बैच फ़ाइल में IF ब्लॉक हो सकता है?


97

एक डॉस बैच फ़ाइल में हम केवल 1 लाइन कर सकते हैं यदि स्टेटमेंट बॉडी? मुझे लगता है कि मुझे कहीं ऐसा लगा कि मैं सी-लाइक प्रोग्रामिंग लैंग्वेज में इस्तेमाल किए जाने वाले आई- ()ब्लॉक की तरह {}इस्तेमाल कर सकता हूं , लेकिन जब मैं यह कोशिश करता हूं तो यह कथनों को निष्पादित नहीं कर रहा है। कोई त्रुटि संदेश भी नहीं। यह मेरा कोड है:

if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7

जब मैं बैच फ़ाइल चलाता हूं, तो न तो "GP प्रबंधक ऊपर है" और न ही "GP प्रबंधक नीचे है" मुद्रित हो जाता है।


हो सकता है कि यह मदद कर सकता है: commandwindows.com/batchfiles-branching.htm
esaj

हां, इससे मदद मिलती है। डॉस बेकार है। अगर मैं कई बयानों का उपयोग करना चाहता हूं, तो क्या मुझे और बयानों के बीच && का उपयोग करना है? या वहाँ एक और अधिक सुंदर तरीका है?
ह्यूग डार्लिंग

जवाबों:


140

आप वास्तव में एक सशर्त के बाद निष्पादित करने के लिए बयानों का एक ब्लॉक बना सकते हैं। लेकिन आपके पास वाक्य रचना गलत है। कोष्ठकों का उपयोग ठीक उसी तरह किया जाना चाहिए जैसा कि दिखाया गया है:

if <statement> (
    do something
) else (
    do something else
)

हालांकि, मैं नहीं मानता कि else-ifबयानों के लिए कोई अंतर्निहित वाक्यविन्यास है । आपको दुर्भाग्य से ifइसे संभालने के लिए बयानों के नेस्टेड ब्लॉक बनाने की आवश्यकता होगी ।


दूसरे, वह %GPMANAGER_FOUND% == trueपरीक्षा मुझे संदिग्ध लगती है। मुझे नहीं पता कि पर्यावरण चर क्या सेट कर रहा है या आप इसे कैसे सेट कर रहे हैं, लेकिन मुझे बहुत संदेह है कि आपके द्वारा दिखाया गया कोड उस परिणाम का उत्पादन करेगा जो आपको लगता है।


निम्नलिखित नमूना कोड मेरे लिए ठीक काम करता है:

@echo off

if ERRORLEVEL == 0 (
    echo GP Manager is up
    goto Continue7
)
echo GP Manager is down
:Continue7

कृपया मेरे नमूना कोड के बारे में कुछ विशेष जानकारी दें:

  • सशर्त विवरण के अंत और उद्घाटन कोष्ठक के बीच स्थान जोड़ा गया।
  • मैं स्थापित करने हूँ @echo offदेखने से रोकने के सभी कंसोल के लिए मुद्रित रूप में वे निष्पादित बयान की, और बदले सिर्फ उन है कि विशेष रूप से के साथ शुरू के उत्पादन में देखना echo
  • मैं बिल्ट-इन ERRORLEVELवैरिएबल को सिर्फ टेस्ट के तौर पर इस्तेमाल कर रहा हूं । और पढ़ें यहाँ

1
% ERRORLEVEL% == 0 का बेहतर उपयोग, क्योंकि दूसरा संस्करण हमेशा सत्य होता है, क्योंकि IFRORLEVEL <N> सही है, अगर त्रुटि बराबर या अधिक <N> है, तो "==" इस मामले में अनदेखा कर रहे हैं
jeb

@ जेब: मुझे लगता है कि आप इस बिंदु से चूक गए होंगे। इस्तेमाल करना ERRORLEVELउसकी समस्या का जवाब नहीं है। मैं बस उचित वाक्यविन्यास का एक उदाहरण पोस्ट कर रहा था। इस मामले में या तो फॉर्म स्वीकार्य है, जैसे कि if 0 == 0कोई अन्य तुच्छ अभिव्यक्ति होगी। लेकिन वास्तव में, सुनिश्चित करें कि आप पर्यावरण चर %ERRORLEVEL%और ERRORLEVELकमांड प्रोसेसर के आंतरिक के बीच अंतर को समझते हैं । रेमंड चेन ने इसे इस ब्लॉग पर अच्छी तरह से समझाया है ।
कोड़ी ग्रे

क्या आपके पास एक ELSE IF हो सकता है?
xagyg

1
@ मिथोफैक्लिऑन की टिप्पणी के साथ, यहां तक ​​कि एक आरई बयान में एक सहज रूप से सहज बंद कोष्ठक ब्लॉक को समाप्त कर देगा। जैसे ब्लॉक REM This is a comment (or so I thought)में फेंकना IFआपको गड़बड़ कर देगा।
rkagerer

2
@Mythofechelon और @rkagerer दोनों एक सामान्य नियम के विशिष्ट मुद्दों की ओर इशारा कर रहे हैं जिन्हें स्ट्रिंग को उद्धृत करने की आवश्यकता है। आपको कभी भी कोड IF %somevar%==example_string2 नहीं करना चाहिए यह हमेशा ऐसा कोड होना चाहिए IF "value_of_somevar"=="example_string2जो IFकथन में सिंटैक्स पैदा करने वाले या तो स्ट्रिंग ऑपरेंड में विशेष वर्णों से बचने का संकल्प करता है। आपके द्वारा निर्धारित मान हमेशा किया जाना चाहिए क्योंकि set "somevar=value_of_somevar" सिंटैक्स आपको चर मानों में विशेष वर्णों से बचने की अनुमति देता है, ध्यान दें। मेरा मतलब यह नहीं है कि set somevar="value_of_somevar"
R

15

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

if %ERRORLEVEL%==0 (
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
)

यह निम्नलिखित मान के साथ var3 प्रदान करना चाहिए :

blue_cheese

लेकिन इसके बजाय पैदावार:

_

क्योंकि सभी 3 कमांड्स को कोड ब्लॉक से बाहर निकलने पर एक साथ कैश और निष्पादित किया जाता है।

मैं इस समस्या को फिर से लिखने में सक्षम था अगर केवल एक कमांड को निष्पादित करने के लिए ब्लॉक - गोटो - और कुछ लेबल जोड़कर। इसकी भद्दी, और मुझे यह पसंद नहीं है, लेकिन कम से कम यह काम करता है।

if %ERRORLEVEL%==0 goto :error0
goto :endif

:error0
set var1=blue
set var2=cheese
set var3=%var1%_%var2%

:endif

8
विलंबित विस्तार का उपयोग करना चाहिए: काम करना चाहिए:set var3=!var1!_!var2!
Dracorat

4

इस गोटो गड़बड़ के बजाय, कमांड विभाजक के रूप में एम्परसेंड और डबल एम्परसेंड और& (त्रुटि करने के लिए सशर्त 0) का उपयोग करने का प्रयास करें।

मैंने इस तरकीब के साथ एक स्क्रिप्ट स्निपेट तय किया, संक्षेप में बताने के लिए, मेरे पास तीन बैच फाइलें हैं, एक जो अन्य दो को कॉल करने के बाद पाया गया कि कौन से अक्षर बाहरी बैकअप ड्राइव को असाइन किए गए हैं। मैं पहली फ़ाइल को प्राथमिक बाहरी ड्राइव पर छोड़ता हूं ताकि इसके बैकअप रूटीन पर कॉल ठीक काम कर सकें, लेकिन दूसरे को कॉल करने के लिए एक सक्रिय ड्राइव परिवर्तन की आवश्यकता होती है। नीचे दिए गए कोड से पता चलता है कि मैंने इसे कैसे तय किया:

for %%b in (d e f g h i j k l m n o p q r s t u v w x y z) DO (
if exist "%%b:\Backup.cmd" %%b: & CALL "%%b:\Backup.cmd"
)

पृथ्वी पर यह नीचे की ओर क्यों है? मुझे ठीक इसी की आवश्यकता थी।
ggb667

1
@ GCB667 - @Louis को स्पष्ट करने के लिए एक "उत्तर" लिखा है जो इस समस्या से संबंधित नहीं है कि आईएफ स्टेटमेंट मूल पोस्टर के लिए काम क्यों नहीं कर रहा था। यह "विनीजेहोनसन" द्वारा एक उत्तर से संबंधित है (जो मूल पोस्टर समस्या से भी चूक गया था) ।
आर

1

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

    if "%COPYTOOL%" equ "R" (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    %TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Robocopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
) else (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    call %TOOLPATH%  "%USERPROFILE%\My Documents\Outlook Files\*" "%USERPROFILE%\My Documents\Outlook Files\_backups" /f /m /v /y
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Xcopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
)

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

भले ही, उत्तरार्द्ध सच हो, एक साधारण समाधान है; एक अलग बैच फ़ाइल या एक बैच फ़ाइल सबरूटीन में कई लाइनों को स्थानांतरित करें। मुझे पता है कि उत्तरार्द्ध दोनों प्रकार की लिपियों में काम करता है।


0

शायद थोड़ी देर हो जाए, लेकिन आशा है कि यह नरक:

@echo off 

if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue1
)
:Continue1
If exist "C:\Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue2
)
:Continue2
If exist "C:\Python31\Lib\site-packages\PyQt4" (  
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue3
)
:Continue3
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue4
)
:Continue4
msg * "Tutto a posto" rem You can relpace msg * with any othe operation...
pause
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.