DOS 배치 파일에 IF 블록을 사용할 수 있습니까?


97

DOS 배치 파일에서 if 문 본문은 한 줄만 가질 수 있습니까? C와 같은 프로그래밍 언어에서 사용되는 ()것과 같은 if 블록에 사용할 수있는 어딘가를 찾았다 고 생각 {}하지만 이것을 시도 할 때 문을 실행하지 않습니다. 오류 메시지도 없습니다. 이것은 내 코드 :

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

이상하게도 배치 파일을 실행할 때 "GP Manager is up"도 "GP Manager is down"도 인쇄되지 않습니다.


아마도 이것이 도움이 될 것입니다 : commandwindows.com/batchfiles-branching.htm
esaj

예, 그게 도움이됩니다. DOS는 형편 없다. if 또는 else 문에서 &&를 사용해야하는 여러 문을 사용하려면? 아니면 더 우아한 방법이 있습니까?
Hugh Darling

답변:


141

실제로 조건문 다음에 실행할 문 블록을 만들 수 있습니다. 그러나 구문이 잘못되었습니다. 괄호는 표시된대로 정확하게 사용해야합니다.

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이면 다른 변형이 항상 참이므로 더 잘 사용하십시오. ERRORLEVEL <N>이 참이면 오류 수준이 <N> 이상이면 "=="는이 경우 무시됩니다
jeb

@jeb : 나는 당신이 요점을 놓친 것 같아요. 사용 ERRORLEVEL은 그의 문제에 대한 답이 아닙니다. 나는 단순히 적절한 구문의 예를 게시했습니다. 이 경우 두 가지 형식 모두 허용됩니다 if 0 == 0. 그러나 실제로 환경 변수 %ERRORLEVEL%ERRORLEVEL명령 프로세서 내부 의 차이점을 이해하고 있는지 확인하십시오 . Raymond Chen 은이 블로그에서 잘 설명합니다 .
Cody Gray

ELSE IF를 가질 수 있습니까?
xagyg 2013

1
@mythofechelon의 주석에 추가하면 REM 문에서 겉보기에 무해한 닫는 괄호조차도 블록을 종료합니다. 예를 들면 던지는 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"
Skip R

15

논리적으로 Cody의 대답 작동합니다. 그러나 명령 프롬프트가 코드 블록을 논리적으로 처리한다고 생각하지 않습니다. 내 인생을 위해 블록 내에서 하나 이상의 명령으로 제대로 작동하도록 할 수는 없습니다. 필자의 경우 광범위한 테스트를 통해 블록 내의 모든 명령이 캐시되고 블록 끝에서 동시에 실행되는 것으로 나타났습니다. 물론 이것은 예상 된 결과를 산출하지 않습니다. 다음은 지나치게 단순화 된 예입니다.

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

이렇게 해야 다음과 같은 값을 VAR3을 제공합니다 :

blue_cheese

그러나 대신 다음을 산출합니다.

_

3 개의 명령이 모두 캐시되고 코드 블록을 종료 할 때 동시에 실행되기 때문입니다.

이 문제는 if 블록을 다시 작성하여 하나의 명령 (goto) 만 실행하고 몇 개의 레이블을 추가하여 극복 할 수있었습니다. 투박하고별로 좋아하지 않지만 적어도 작동합니다.

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 조건부)를 명령 구분 기호로 사용해보십시오.

요약하자면이 트릭으로 스크립트 스 니펫을 수정했습니다. 요약하면, 외부 백업 드라이브에 할당 된 문자를 찾은 후 다른 두 개를 호출하는 배치 파일이 3 개 있습니다. 첫 번째 파일을 기본 외장 드라이브에 남겨 두어 백업 루틴에 대한 호출이 정상적으로 작동했지만 두 번째 파일에 대한 호출에는 활성 드라이브 변경이 필요했습니다. 아래 코드는 수정 방법을 보여줍니다.

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 2014 년

1
@ GCB667-@Louis를 명확히하기 위해 IF 문이 원본 포스터에서 작동하지 않는 이유에 대한 문제와 관련이없는 "답변"을 작성했습니다. "vinniejohnson"의 대답과 관련이 있습니다 (원본 포스터 문제도 놓 쳤음). .
Skip R

1

배치 파일의 IF 명령과 관련된 검색 결과에서이 기사를 살펴 보았고 IF 블록이 단일 명령으로 제한된다는 오해를 수정할 기회를 거부 할 수 없었습니다. 다음은이 응답을 작성하는 시스템에서 매일 실행되는 프로덕션 Windows NT 명령 스크립트의 일부입니다.

    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%
)

아마도 두 줄 이상의 블록은 Windows NT 명령 스크립트 (.CMD 파일)에만 적용됩니다. 구식 배치 (.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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.