गुरुत्वाकर्षण के शानदार उत्तर पर विस्तार:
सबसे पहले, अपने प्रश्न का उत्तर देने के लिए:
जब% CHECKCONTINUE% को शून्य मान दिया जाता है तो बैच स्क्रिप्ट को समाप्त क्यों किया जाता है?
समस्या यह है कि लाइन 16 में, आप यह करते हैं:
if %CHECKCONTINUE%==n GOTO exit
जबसे CHECKCONTINUE
"अपरिभाषित" है, यह एक "खाली" स्ट्रिंग का मूल्यांकन करता है, इसलिए लाइन 16 पर बयान वास्तव में कर रहा है:
if ==n GOTO exit
यह एक अमान्य कथन है क्योंकि बाएं हाथ की तरफ कुछ भी नहीं है "=="
। इसलिए, जब वह अनुचित रूप से प्रारूपित विवरण निष्पादित करने का प्रयास करता है, तो बैच स्क्रिप्ट समाप्त हो जाती है:
C:\>script.cmd
I'm about to...
1.) Remove the registry data that specifies settings for TF2
2.) Forcibly disable Steam Cloud.
Okay to continue? (y/n): <ENTER key pressed>
GOTO was unexpected at this time.
C:\>
यदि आपको किसी व्यक्ति के पास कोई ऐसी चीज़ है, जिसमें कोई स्थान हो तो आपको एक समान समस्या होगी:
C:\>script.cmd
I'm about to...
1.) Remove the registry data that specifies settings for TF2
2.) Forcibly disable Steam Cloud.
Okay to continue? (y/n): Yes please
please==n was unexpected at this time.
C:\>
इसे ठीक करने के लिए, आपको इस तरह शब्दों के चारों ओर दोहरे उद्धरण चिह्नों का उपयोग करना चाहिए:
if "%CHECKCONTINUE%"=="n" GOTO :exit
यह आवश्यक है यदि उपयोग किए जाने वाले चर "खाली" हो सकते हैं या यदि वे व्हाट्सएप एम्बेडेड हो सकते हैं, लेकिन इसका मूल्यांकन करते समय हमेशा दोहरे उद्धरण चिह्नों का उपयोग करना एक अच्छा विचार है। "=="
।
नोट: कुछ त्रुटियां (जैसे ऊपर वाले के साथ "if"
तथा "=="
"घातक" त्रुटियां हैं जो बैच स्क्रिप्ट के निष्पादन को तुरंत रोक देंगी। अन्य त्रुटियाँ (जैसे नीचे दी गई हैं) "set"
), "गैर-घातक" त्रुटियां हैं। "गैर-घातक" त्रुटियों के लिए, त्रुटि वाले बयान को निष्पादित नहीं किया जाता है, एक त्रुटि संदेश दिखाया जाता है, और बैच स्क्रिप्ट अगले बयान से शुरू होती है
अगला, जैसा कि इस लाइन के बारे में बताया गया है:
set %CHECKCONTINUE%=
यह CHECKCONTINUE को संशोधित नहीं करता है, लेकिन चर नाम के रूप में इसके मूल्य का उपयोग करता है।
फिर, अगर CHECKCONTINUE
"अपरिभाषित" था, यह "खाली" स्ट्रिंग का मूल्यांकन करेगा, इसलिए कथन वास्तव में कर रहा है:
set =
यह एक अमान्य कथन भी है क्योंकि बाएं हाथ की तरफ कुछ भी नहीं है "="
।
और ये पंक्तियाँ:
if defined %CHECKCONTINUE% GOTO loop-notvalid
if not defined %CHECKCONTINUE% GOTO loop-noreply
"if defined"
(तथा "if not defined"
) एक चर नाम की अपेक्षा करता है, चर का मान नहीं। अगर CHECKCONTINUE
अपरिभाषित था, %CHECKCONTINUE%
एक रिक्त स्ट्रिंग का मूल्यांकन करेगा, और ये कथन वास्तव में होंगे:
if defined GOTO loop-notvalid
if not defined GOTO loop-noreply
यहाँ, "if defined"
(तथा "if not defined"
) की जाँच करने जा रहा है अगर एक चर नाम दिया है GOTO
परिभाषित किया गया है या नहीं।
इसके अलावा, इन 3 लाइनों के लिए, यदि CHECKCONTINUE
वास्तव में परिभाषित किया गया था, "set"
तथा "if defined"
पर काम करेंगे "value"
के बजाय, चर की "name"
चर का ही। तो अगर CHECKCONTINUE
पहले से ही एक मूल्य था "y"
, फिर:
set %CHECKCONTINUE%=
if defined %CHECKCONTINUE% goto loop-notvalid
if not defined %CHECKCONTINUE% goto loop-noreply
वास्तव में इस रूप में देखा जाएगा:
set y=
if defined y goto loop-notvalid
if not defined y goto loop-noreply
उदाहरण "script.cmd":
@set "CHECKCONTINUE="
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" (undefined/empty).
@rem ## 05: set %CHECKCONTINUE%=
set %CHECKCONTINUE%=
@echo This doesn't set the value of of the variable named "CHECKCONTINUE".
@echo Since no variable name is actually specified, it is an error.
@set "CHECKCONTINUE=yes"
@set "yes=something"
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" and the value of the variable named "yes"="%yes%"
@rem ## 17: set %CHECKCONTINUE%=
set %CHECKCONTINUE%=
@echo This doesn't set the value of the variable named "CHECKCONTINUE".
@echo Since CHECKCONTINUE="%CHECKCONTINUE%", it sets the value of the variable named
@echo "%CHECKCONTINUE%". No error is shown because the statement is valid.
@echo It could have been a problem (well, at least a big annoyance) if
@echo CHECKCONTINUE had the value: "path". The statement
@echo should be: set "CHECKCONTINUE="
@rem ## 27: echo CHECKCONTINUE still has the value: "%CHECKCONTINUE%"
@echo CHECKCONTINUE still has the value: "%CHECKCONTINUE%"
@rem ## 30: echo and the variable named "%CHECKCONTINUE%" is now empty="%yes%"
@echo and the variable named "%CHECKCONTINUE%" is now empty="%yes%"
@set "yes="
@set "CHECKCONTINUE="
@set "echo=something"
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" (undefined) and the value of the variable
@rem ## named "echo"="%echo%".
@rem ## 41: if defined %CHECKCONTINUE% echo Variable is defined.
if defined %CHECKCONTINUE% echo Variable is defined.
@echo This doesn't check if the variable named "CHECKCONTINUE" is defined.
@echo Since it's "empty", it is skipped (well, there is nothing there to
@echo "skip") and "if defined" is checking the next word (which is "echo").
@echo What's left is: if defined echo Variable is defined.
@echo So, it checks if a variable named "echo" is defined (which it is).
@echo Since "if defined" has checked a variable named "echo", it then tries
@echo to execute the rest of the line starting with the word "Variable",
@echo as a command. This fails and is an error. The statement
@echo should be: if defined CHECKCONTINUE echo Variable is defined.
@set "echo="
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" (undefined) and "echo"="%echo%" (undefined).
@rem ## 59: if not defined %CHECKCONTINUE% echo The-variable-is-not-defined.
if not defined %CHECKCONTINUE% echo The-variable-is-not-defined.
@echo Similar: Since "if not defined" has checked a variable named "echo"
@echo (which is "undefined"), it then tries to execute the rest of the
@echo line: "The-variable-is-not-defined." as a command. This fails and is
@echo an error. The statement
@echo should be: if not defined CHECKCONTINUE echo The-variable-is-not-defined.
@set "echo=something"
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" (undefined) and "echo"="%echo%".
@rem ## 73: if defined %CHECKCONTINUE% echo Verify this.
if defined %CHECKCONTINUE% echo Verify this.
@echo Again, similar: Since "if defined" has checked a variable named
@echo "echo", it then tries to execute the rest of the line starting with
@echo the word: "Verify" as a command. This happens to be a valid command
@echo but it also fails because of an incorrect parameter for the command.
@echo The statement should be: if defined CHECKCONTINUE echo Verify this.
@set "echo="
@set "CHECKCONTINUE=yes"
@set "yes="
@rem ## CHECKCONTINUE="%CHECKCONTINUE%" and the variable named "yes"="%yes%" (undefined).
@rem ## 90: if not defined %CHECKCONTINUE% echo CHECKCONTINUE is not defined.
if not defined %CHECKCONTINUE% echo CHECKCONTINUE is not defined.
@echo Here "CHECKCONTINUE" is defined, but "if not defined" still doesn't
@echo check if the variable named "CHECKCONTINUE" is defined. Since
@echo CHECKCONTINUE has a value of "%CHECKCONTINUE%", "if not defined" is
@echo checking if a variable named "%CHECKCONTINUE%" is defined (which it isn't).
@echo This causes "if not defined" to proceed and echo the message when
@echo that's probably not what was intended. The statement
@echo should be: if not defined CHECKCONTINUE echo CHECKCONTINUE is not defined.
"Script.cmd" चलाने से आपको मिलेगा:
## CHECKCONTINUE="" (undefined/empty).
## 05: set %CHECKCONTINUE%=
C:\>set =
The syntax of the command is incorrect.
This doesn't set the value of of the variable named "CHECKCONTINUE".
Since no variable name is actually specified, it is an error.
## CHECKCONTINUE="yes" and the value of the variable named "yes"="something"
## 17: set %CHECKCONTINUE%=
C:\>set yes=
This doesn't set the value of the variable named "CHECKCONTINUE".
Since CHECKCONTINUE="yes", it sets the value of the variable named
"yes". No error is shown because the statement is valid.
It could have been a problem (well, at least a big annoyance) if
CHECKCONTINUE had the value: "path". The statement
should be: set "CHECKCONTINUE="
## 27: echo CHECKCONTINUE still has the value: "%CHECKCONTINUE%"
CHECKCONTINUE still has the value: "yes"
## 30: echo and the variable named "yes" is now empty="%yes%"
and the variable named "yes" is now empty=""
## CHECKCONTINUE="" (undefined) and the value of the variable
## named "echo"="something".
## 41: if defined %CHECKCONTINUE% echo Variable is defined.
C:\>if defined echo Variable is defined.
'Variable' is not recognized as an internal or external command,
operable program or batch file.
This doesn't check if the variable named "CHECKCONTINUE" is defined.
Since it's "empty", it is skipped (well, there is nothing there to
"skip") and "if defined" is checking the next word (which is "echo").
What's left is: if defined echo Variable is defined.
So, it checks if a variable named "echo" is defined (which it is).
Since "if defined" has checked a variable named "echo", it then tries
to execute the rest of the line starting with the word "Variable",
as a command. This fails and is an error. The statement
should be: if defined CHECKCONTINUE echo Variable is defined.
## CHECKCONTINUE="" (undefined) and "echo"="" (undefined).
## 59: if not defined %CHECKCONTINUE% echo The-variable-is-not-defined.
C:\>if not defined echo The-variable-is-not-defined.
'The-variable-is-not-defined.' is not recognized as an internal or external command,
operable program or batch file.
Similar: Since "if not defined" has checked a variable named "echo"
(which is "undefined"), it then tries to execute the rest of the
line: "The-variable-is-not-defined." as a command. This fails and is
an error. The statement
should be: if not defined CHECKCONTINUE echo The-variable-is-not-defined.
## CHECKCONTINUE="" (undefined) and "echo"="something".
## 73: if defined %CHECKCONTINUE% echo Verify this.
C:\>if defined echo Verify this.
An incorrect parameter was
entered for the command.
Again, similar: Since "if defined" has checked a variable named
"echo", it then tries to execute the rest of the line starting with
the word: "Verify" as a command. This happens to be a valid command
but it also fails because of an incorrect parameter for the command.
The statement should be: if defined CHECKCONTINUE echo Verify this.
## CHECKCONTINUE="yes" and the variable named "yes"="" (undefined).
## 90: if not defined %CHECKCONTINUE% echo CHECKCONTINUE is not defined.
C:\>if not defined yes echo CHECKCONTINUE is not defined.
CHECKCONTINUE is not defined.
Here "CHECKCONTINUE" is defined, but "if not defined" still doesn't
check if the variable named "CHECKCONTINUE" is defined. Since
CHECKCONTINUE has a value of "yes", "if not defined" is
checking if a variable named "yes" is defined (which it isn't).
This causes "if not defined" to proceed and echo the message when
that's probably not what was intended. The statement
should be: if not defined CHECKCONTINUE echo CHECKCONTINUE is not defined.
इसके अलावा, एक विकल्प के रूप में "set /p"
, आप उपयोग कर सकते हैं "choice"
:
@echo off
title Registry restore script
rem Restores registry settings and disables the cloud
rem "quotes" around variable name and value for set visibly shows what
rem the variable is being set to and prevents accidentally including
rem trailing whitespace in the variable's value.
set "CHECKCONTINUE="
:listaction
echo I'm about to...
echo 1.) Remove the registry data that specifies settings for TF2
echo 2.) Forcibly disable Steam Cloud.
echo.
choice /c yn /M "Okay to continue"
set "CHECKCONTINUE=%errorlevel%"
if %CHECKCONTINUE% EQU 1 @echo Pressed Y && goto :start
if %CHECKCONTINUE% EQU 2 @echo Pressed N && goto :exit
if %CHECKCONTINUE% EQU 0 @echo Pressed Ctrl-C+n
@echo.
@echo Terminate batch job cancelled. You must enter a reply. Press n to exit.
@echo.
goto :listaction
rem The remainder of your code goes here ...
नोट: लेबल पर कोड: "loop-notvalid"
आवश्यक नहीं है क्योंकि "पसंद" अपरिभाषित प्रतिक्रियाओं (y / n) को स्वीकार नहीं करेगा।
इसके अलावा, "पसंद" कॉमनड से "खाली" प्रतिक्रिया प्राप्त करने का एकमात्र तरीका है, यदि उपयोगकर्ता बैच की नौकरी समाप्त करने के लिए "Ctrl-C" दबाता है, और फिर "टर्मिनेट बैच नौकरी" (Y /) में एन (नहीं) में प्रवेश करता है। एन)? " संकेत मिलता है, यह दर्शाता है कि वे बाहर नहीं निकलना चाहते हैं। ऊपर दिए गए कोड को पकड़ता है और एक संदेश को प्रिंट करता है (फिर एक बार) उपयोगकर्ता को फिर से संकेत देने के लिए ": सूची" लेबल पर कूदता है (इसलिए), इसलिए आपको "लूप-नॉरप्ली" लेबल पर कोड की आवश्यकता नहीं है।
चॉइस कमांड का ध्यान रखने के बाद से "रिसेट" त्रुटि करने की कोई आवश्यकता नहीं है। और, यह स्पष्ट करने के लिए आवश्यक नहीं है CHECKCONTINUE
चर क्योंकि यह हमेशा के बराबर सेट है %errorlevel%
के मूल्य से पहले CHECKCONTINUE
जांच की जाती है।
डिफ़ॉल्ट रूप से, पसंद "केस-असंवेदनशील" है, इसलिए "Y" या "N" को दबाने पर "y" या "n" दबाने के समान है। यह व्यवहार निर्दिष्ट करके बदला जा सकता है /cs
पसंद कमांड लाइन पर।