중력의 중대한 대답에 확장 :
첫째, 귀하의 질문에 대답 :
왜 % CHECKCONTINUE %에 null 값이 주어지면 배치 스크립트가 종료됩니까?
문제는 16 번 줄에서 다음과 같이하는 것입니다.
if %CHECKCONTINUE%==n GOTO exit
이후 CHECKCONTINUE
"undefined"이면 "빈"문자열로 평가되므로 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를 수정하지 않고 그 값을 변수 이름으로 사용합니다.
다시, if CHECKCONTINUE
"undefined"였을 때, 그것은 "empty"문자열로 평가 될 것이고, 그래서 그 문장은 실제로 수행 중이다 :
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
정의되어 있는지 여부.
또한이 세 줄의 경우 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 / N)"입력란에 N (아니오)을 입력하면 "선택" 엔)?" 그들은 종료하고 싶지 않다는 것을 나타내는 프롬프트. 위의 코드는이를 잡아 내고 메시지를 출력 한 다음 ": listaction"레이블로 이동 (goto)하여 사용자에게 다시 프롬프트를 표시하므로 "loop-noreply"레이블에서도 코드가 필요하지 않습니다.
선택 명령이이를 처리하므로 오류 레벨을 "재설정"할 필요가 없습니다. 그리고 광고를 삭제할 필요가 없습니다. CHECKCONTINUE
변수는 항상 같게 설정되기 때문에 %errorlevel%
가치가 있기 전에 CHECKCONTINUE
검사 받는다.
기본적으로 선택 사항은 "대소 문자를 구별하지 않습니다"이므로 "Y"또는 "N"을 누르면 "y"또는 "n"을 누르는 것과 같습니다. 이 동작은 다음을 지정하여 변경할 수 있습니다. /cs
선택 명령 행에.