노무현 대통령 배너
BLOG main image
왕미친놈의 왕미친세상입니다. 미친 소리는 써도 되지만, 근거 없는 소리는 쓰면 안 됩니다.


들어가며

IF ERRORLEVEL문은 방금 실행을 마친 프로그램의 종료코드(마침코드)를 비교하여 프로그램 수행을 결정하는 구문이다. 이를 위해 몇 가지 프로그램의 종료코드를 소개하고자 한다. 또한 이러한 종료코드는 ERRORLEVEL 환경변수(%ERRORLEVEL%)에 저장하여 이용할 수도 있다.

말뜻

종료코드(마침코드)는 프로그램이 수행 과정에서 어떻게 처리하였는지를 알려주는 정수를 가리킨다. 주로 정수 0은 정상 종료되었음을 뜻하면 1보다 크거나 같은 값은 오류가 발생했음을 뜻한다. 프로그램이 종료하면서 운영체제에 넘겨주기 때문에 종료코드라는 이름이 붙었다.

여러 프로그램의 종료코드

윈도XP의 도움말 및 지원 센터의 내용에 따르면 다음과 같은 종료코드를 가지고 있다고 한다.

  • diskcomp : 두 플로피디스크를 비교하는 명령어

    • 0 : 두 플로피디스크가 같다. (정상 종료)
    • 1 : 차이를 발견했다.
    • 2 : 하드웨어 오류 발생.
    • 3 : 초기화 오류 발생.
  • xcopy : 하위 디렉터리와 파일을 복사하는 명령어

    • 0 : 파일이 오류 없이 복사됨. (정상 종료)
    • 1 : 복사할 파일을 찾지 못하다.
    • 2 : 사용자가 Ctrl+C를 눌러 강제 종료.
    • 4 : 초기화 오류가 발생. 메모리나 디스크 공간 부족, 명령줄에 잘못된 드라이브 이름이나 잘못된 구문을 입력했을 때 생긴다.
    • 5 : 디스크 쓰기 오류가 발생했습니다.
  • color : 전경색(글자색)과 배경색을 지정하고 복원하는 명령어

    • 0 : 전경색과 배경색이 다르다.
    • 1 : 전경색과 배경색이 같다.
  • diskcopy : 플로피디스크에서 다른 플로피디스크로 복사하는 명령어

    • 0 : 복사 성공. (정상 종료)
    • 1 : 치명적이지 않은 읽기/쓰기 오류가 발생
    • 3 : 치명적인 하드웨어 오류가 발생
    • 4 : 초기화 오류가 발생
  • format : 디스크를 초기화하는 명령어

    • 0 : 포맷을 성공했습니다.  (정상 종료)
    • 1 : 잘못된 매개 변수를 입력
    • 4 : 치명적인 오류가 발생 (0, 1 또는 5를 제외한 오류).
    • 5 : "포맷을 실행하시겠습니까(Y/N)?" 메시지에서 N 키를 눌러 실행이 중단됨.
  • graftabl : 그래픽 모드에서 확장 문자 집합을 표시하는 기능을 사용 가능하게 설정합니다.

    • 0 : 문자 집합을 기억장치에 읽어들이는 데 성공. 이전 코드 페이지는 로드되지 않는다. (정상 종료)
    • 1 : 잘못된 매개 변수. 작업이 수행되지 않는다.
    • 2 : 파일 오류가 발생
  • replace : 대상 디렉터리의 파일을 이름이 같은 원본 디렉터리의 파일로 바꾼다. replace를 사용하여 대상 디렉터리에 고유 파일 이름을 추가할 수도 있다.

    • 0 : replace 명령이 성공적으로 파일을 바꾸거나 추가했습니다. (정상 종료)
    • 1 : replace 명령이 맞지 않는 MS-DOS 버전을 발견했습니다.
    • 2 : replace 명령이 원본 파일을 찾을 수 없습니다.
    • 3 : replace 명령이 원본이나 대상 경로를 찾을 수 없습니다.
    • 5 : 사용자는 바꾸고자 하는 파일을 액세스할 수 없습니다.
    • 8 : 명령을 실행할 시스템 메모리가 부족합니다.
    • 11 : 명령줄에 잘못된 구문을 사용했습니다.
  • 그밖에 마이크로소프트 제품의 setup.exe 프로그램 : 윈도용 애플리케이션의 설치 프로그램

    • 0 : 프로그램 설치를 성공 또는 사용자가 취소한 경우. (정상 종료)
    • 0 이외의 값 : 프로그램 설치 도중에 프로그램 오류 발생
  • 고스트 등의 시만텍 사의 프로그램

    • 0 : 오류가 발생하지 않고 정상 종료
    • 0 이외의 값 : 오류가 발생

예제 1

IF ERRORLEVEL문과 ELSE를 함께 사용한 예제는 GBackup1H2P.cmd 파일이다. 지난번에 작성한 GBackup1H2P.cmd을

GBackup1H2P-1.cmd로 이름을 바꾸어 저장하고, GBackup1H2P.cmd을 편집해 보자.

  1. GHOST.exe -CLONE,MODE=PDUMP,SRC=1:1,DST=1:2\GHOST.GHO -Z9 -AUTO -SURE -RB
  2.  
  3. REM IF-ELSE 구문 : 오류가 발생하면 오류 발생을 알려준다.
  4. IF ERRORLEVEL 1 (
  5.     ECHO ##############################################
  6.     ECHO ##      백업 도중 오류가 발생했습니다.      ##
  7.     ECHO ##############################################
  8. ) ELSE (
  9.     ECHO ##############################################
  10.     ECHO ##    백업 작업을 정상적으로 마쳤습니다.    ##
  11.     ECHO ##############################################
  12. )

바뀐 부분만 나타내면 위와 같다. 이때 IF는 '('와 같은 명령줄에 있어야 하며, ')'와 ELSE가 같은 명령줄에 있어야 한다. 또한 ELSE는 뒤따르는 '('와 같은 명령줄에 있어야 한다.

  • 참고 : 앞서 말했듯이 위 코드는 정상 작동하지 않는다. 다만 ERRORLEVEL 검사는 잘 된다.

예제 2

XCOPY를 이용한 백업 유틸리티를 제작해 보았다.

  1. @echo off
  2. rem 파일명 : Xback.bat
  3. rem 지은이 : koc2000/SALM
  4. rem 저작권 : GPL v3
  5.  
  6. rem 예제 12.
  7. rem XCOPY를 이용한 백업
  8. rem 사용법 : Xback  원본디렉터리  대상디렉터리
  9.  
  10. rem 작업 1 : 매개변수가 있는가? 없으면 도움말을 보여준다.
  11. IF NOT * == %2* (
  12.     REM 매개변수가 모두 있으면 작업을 시작한다.
  13.     REM XCOPY 명령을 이용해 백업합니다.
  14.     XCOPY %1 %2 /i /S /E /H /M
  15.  
  16.     REM 종료코드가 4 또는 그보다 크면
  17.     IF ERRORLEVEL 4 (
  18.         echo 파일을 백업하기에는 메모리가 부족하거나
  19.         echo 드라이브가 잘못 지정되었거나 명령줄 구문이 틀립니다.
  20.     ) ELSE IF ERRORLEVEL 2 (
  21.         echo 사용자가 CTRL+C를 눌러 백업 작업을 강제 종료했습니다.
  22.     ) ELSE IF ERRORLEVEL 0 (
  23.         echo 백업을 정상적으로 성공했습니다.
  24.     )
  25. ) ELSE (
  26.     REM 매개변수가 없으면 메시지를 보인 뒤 사용법을 보여준다.
  27.  
  28.     ECHO 매개변수가 없거나 모자랍니다.
  29.     ECHO 구문 : Xback  source_dir  backup_dir
  30. )
  31.  
  32. :END

위 구문에서 11행의 " IF NOT * == %2* ( " 부분은 문자열 비교문에서 다시 설명하기로 한다.

또한 위의 코드에서 ERRORLEVEL 값이 큰 값부터 차례대로 낮아지게 만드는 것이 배치파일에서는 묵시적 원칙입니다. 이는 실수로 일어날 수 있는 오류를 막기 위한 방법이지요. 왜냐하면 IF ERRORLEVEL 구문은 "같은 값"을 구하는 구문이 아니기 때문입니다.

  1. IF [NOT] ERRORLEVEL 정수 명령어

위와 같은 경우 정수보다 크거나 같으면 뒤따르는 명령어를 실행하게 되어 있습니다.

  1. IF ERRORLEVEL 1 command01
  2. IF ERRORLEVEL 2 command02
  3. IF ERRORLEVEL 3 command03
  4. IF ERRORLEVEL 4 command04
  5. IF ERRORLEVEL 15 command15

만약에 command01을 실행하고, command02부터는 실행하지 않을 생각이었다면 위와 같은 코드는 작성해서는 안됩니다. 위의 코드는 ERRORLEVEL이 1일 때만 정상 작동하고, 나머지 경우는 항상 사용자가 원하지 않는 작동을 하게 됩니다.

반드시 command01 명령만 실행하겠다면 다음과 같은 두 가지 방법이 있습니다.

  1. rem 방법1
  2. IF ERRORLEVEL 15 command15
  3. IF ERRORLEVEL 4 command04
  4. IF ERRORLEVEL 3 command03
  5. IF ERRORLEVEL 2 command02
  6. IF ERRORLEVEL 1 command05

우선 첫 방법으로는 위와 같이 큰 수부터 비교합니다. 2행에서는 종료코드가 15보다 크거나 같으면 command15 명령을 실행하게 되지요. 그러나 다음 행에 나오는 구문이 실행될 여지는 여전히 남습니다.

그럴 경우 다른 방법으로는 아래와 같이 정확한 수를 비교하게 만듭니다. 2행에서는 종료코드가 15보다 크거나 같고, 16보다 크거나 같지 않으면(작으면), 실행한다는 뜻입니다. 이러한 경우는 종료코드가 정확히 15인 경우뿐입니다.

  1. rem 방법2
  2. IF ERRORLEVEL 15 IF NOT ERRORLEVEL 16 command15
  3. IF ERRORLEVEL 4 IF NOT ERRORLEVEL 5 command04
  4. IF ERRORLEVEL 3 IF NOT ERRORLEVEL 4 command03
  5. IF ERRORLEVEL 2 IF NOT ERRORLEVEL 3 command02
  6. IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 command05

방법1에서는 goto 명령을 사용할 경우 오류가 생기지 않지만, 일반 명령을 사용할 경우에는 오류가 생길 수 있습니다.

방법2에서는 애초에 정확한 값을 비교하게 되므로 오류가 상당히 줄어들게 됩니다.

이와 비슷한 방법으로는 아래처럼 %ERRORLEVEL%을 쓰는 명령 확장이 있습니다.

  1. if /i %ERRORLEVEL% EQU 15 command15

위 문장은 문자열을 비교해 주는 if 구문입니다. 그런데 /i 선택사항이 들어감으로써 융통성을 지니게 되어 일반적인 비교를 하게 됩니다.

  1. IF ERRORLEVEL 4 (
  2.         echo 파일을 백업하기에는 메모리가 부족하거나
  3.         echo 드라이브가 잘못 지정되었거나 명령줄 구문이 틀립니다.
  4. ) ELSE IF ERRORLEVEL 2 (
  5.         echo 사용자가 CTRL+C를 눌러 백업 작업을 강제 종료했습니다.
  6. )

위의 부분은 if 구문에 뒤따르는 명령이 하나가 아닐 때 쓰는 방법입니다. 명령이 하나가 아니라는 말은 같은 명령을 두 번 이상 쓸 경우에도 해당합니다. 위의 문장은 echo 명령을 두 번 썼기 때문에 ( ) (괄호)로 묶어야 합니다. 이러한 구문은 도스의 if와는 호환성이 없는 명령 확장 가운데 하나입니다.

또한 위에서 나타난 else 명령은 반드시 if 문의 끝에만 쓰일 수 있습니다. 또한 else 앞에는 반드시 ) (닫는 괄호)가 와야 합니다. 이때 else의 뜻은 "~이지 않고"라는 뜻이고, 위의 상황에서는 "종료코드가 4보다 크거나 같지 않고"라는 뜻이 됩니다. 뒤따르는 if 구문까지 합해서 해석하면 "종료코드가 4보다 작고, 2보다 크거나 같으면"이라는 뜻이 되지요. 종료코드가 3일 수도 있지만, XCOPY 명령은 종료코드 3을 가지지 않으므로 위의 구문은 정확히 실행됩니다.

또한 위의 방식은 구조적 프로그래밍 또는 절차적 프로그래밍에 근접한 방식입니다. GOTO 명령은 최대한 억제하여 꼭 필요한 경우에만 써야 읽기 좋고, 알아보기 좋고, 고치기 쉬운 코드가 됩니다.

관련 문서

다음 예고

이 글은 스프링노트에서 작성되었습니다.

'스크립트 > 배치파일' 카테고리의 다른 글

IF 문자열  (4) 2009.04.18
IF EXIST  (0) 2009.04.15
IF ERRORLEVEL에 쓰이는 종료코드  (12) 2009.04.14
IF 기본 설명  (6) 2009.04.09
배치파일에 매개변수 전달하기 2  (5) 2009.04.04
배치파일에 매개변수 전달하기  (0) 2009.04.01
글쓴이는 koc/SALM입니다.
본문에 저작권에 대한 사항이 나타나지 않거나, 저작권이 BY-SA로 표기되어 있다면,
이 글은 GFDL로 공개한 글입니다.

댓글을 달아주세요:: 왕미친놈 욕은 해도 되지만, 근거없는 소리는 쓰지 말아 주세요.
BBCode 사용할 수 있습니다.

  1. 진만고양이
    2010.04.06 11:48
    GHOST.exe -CLONE,MODE=PDUMP,SRC=1:1,DST=1:2\GHOST.GHO-CLONE,MODE=PDUMP,SRC=1:1,DST=1:2\GHOST.GHO -Z9 -AUTO -SURE -RB

    IF ERRORLEVEL 1 (

    ECHO FAULT

    ) ELSE (

    ECHO EXEUTE
    )

    라고 보면..

    저같은 경우 고스트 프로그램이 없으므로

    0이아닌 에러 레벨이나와서(1,2,3,등)

    if ERRORLEVEL 1 ->>> 이부분에서 참이 되는거 맞나요??? 에러레벨이 1이상이면 전부 1로 봐야되나요?
    • 2010.04.06 12:24
      댓글 주소 수정/삭제
      IF ERRORLEVEL 정수
      위 구문의 뜻은 "종료코드가 정수와 같거나 크면"이라는 뜻입니다. 다시 말해 정확하게 그 정수를 뜻하지는 않습니다.
      정확하게 종료코드 1을 알아내는 구문은 다음과 같습니다.
      if ERRORLEVEL 1 if not ERRORLEVEL 2
      위 구문을 해석하면 " 종료 코드가 1보다 크거나 같으면, (그리고) 종료 코드가 2와 같지 않고 크지도 않으면" 이라는 뜻입니다.

      다른 방법으로 if 문이 여럿 있을 때...
      if ERRORLEVEL 9 명령1
      if ERRORLEVEL 8 명령2
      if ERRORLEVEL 7 명령3
      ...
      if ERRORLEVEL 2 명령8
      if ERRORLEVEL 1 명령9
      이런 식으로 종료코드가 큰 값부터 차례대로 작게 작성하면 됩니다.

      또한 ghost.exe 파일이 있는지를 먼저 검사하여 오류를 줄이면 됩니다. if exist 구문 참조
  2. 진만고양이
    2010.04.06 13:45
    답변 감사합니다.. 주인장님 (^^)(__)

    ghost.exe 파일이 없으면 어떤값을 리턴을 해주는건가요??

    0보다 큰 값을 리턴해주어서

    위에서
    IF ERRORLEVEL 1 부분이 참이되어 폴트가 출력되는게 맞는지요?

    테스트해봤는데.. ghost.exe 파일이 없을때

    C:\shell-test>iftest01.bat
    'GHOST.exe'은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
    배치 파일이 아닙니다.
    ##########################################
    ## 백업 도중 오류가 발생했습니다. ##
    ##########################################
    C:\shell-test>

    라고 뜹니다. 제가 이해한게 맞죠? ''?
    • 2010.04.06 15:26
      댓글 주소 수정/삭제
      파일이 없으면 ghost.exe에서 오류코드를 넘겨주지는 않습니다.
      다만 도스의 command.com 파일이 오류코드를 넘겨줍니다. 이때도 1 또는 그보다 큰 값이 넘어옵니다.
      앞의 오류 메시지를 보이지 않게 하려면 if exist 구문을 써서 파일이 있는지를 먼저 검사하면 됩니다.
  3. 진만고양이
    2010.04.07 13:58
    @REM iftest03.bat 파일임
    @echo off

    IF EXIST GHOST.exe (
    ECHO 파일있음
    GHOST.exe -CLONE,MODE=PDUMP,SRC=1:1,DST=1:2\GHOST.GHO -Z9 -AUTO -SURE-SURE -RB
    IF NOT ERRORLEVEL 1 GOTO NOERROR
    ECHO ##############################################
    ECHO ## 백업 도중 오류가 발생했습니다. ##
    ECHO ##############################################
    GOTO END

    :NOERROR
    ECHO ##############################################
    ECHO ## 백업 작업을 정상적으로 마쳤습니다. ##
    ECHO ##############################################
    GOTO END

    ) ELSE (
    ECHO 파일 없어용
    )

    :END
    ECHO ......
    REM 이때 %ERRORLEVEL% 환경변수는 일종의 SET 명령명령 확장에 해당한다.
    EXIT /B %ERRORLEVEL%



    =====
    위처럼 바꿧는데 돌아갑니다.

    결과값이

    파일없음
    ..........

    이렇게나오는데 궁금한것은 ghost.exe 가돌아갈때
    if문 에서 errorlevel 체크부분이 제대로 돌아가는지 궁금하네요
    • 2010.04.07 21:18
      댓글 주소 수정/삭제
      ghost.exe 파일은 도스용입니다. 윈도의 명령 프롬프트(흔히 '도스창')에서는 항상 오류가 납니다.

      반면에 도스 상태에서는
      IF EXIST GHOST.exe (
      구문에서 오류가 납니다.
      도스용 if 구문에서는 괄호( ( )를 지원하지 않습니다. 다시 말해 여는 괄호를 명령어로 인식하기 때문에 오류가 나고 맙니다.
  4. 진만고양이
    2010.04.07 14:01
    궁금 2)
    EXIT /B %ERRORLEVEL%


    이것이 이해가 안되네요.
    위에서 이것을 넣고 안넣고 하면
    출력할때 빈줄이 하나더 나오나 안나오냐이던데

    exit /h 하면
    번호를 지정합니다. /B가 지정되면 ERRORLEVEL을
    지정한 번호로 설정합니다. CMD.EXE를 끝내면,
    프로세스 종료 코드를 지정한 번호로 설정합니다.

    라고 설명되어잇는데 말이 무슨말인지 햇갈려용 쉽게 설명 좀 ^^;; 부탁드립니다.
    • 2010.04.07 21:19
      댓글 주소 수정/삭제
      if errorlevel 구문에서 쓰는 오류코드(종료코드)의 값을 사용자가 직접 지정할 수 있다는 뜻입니다.

      윈도용에서만 지원하고, 도스용에서는 지원하지 않는 기능입니다.
  5. 진만고양이
    2010.04.08 13:59
    안녕하세요~!
    제가 질문을 많이하죠? ^^ㅋ
    궁금한것이 있으면 풀어야 직성이 풀려서요
    에러레벨 코드 관련 질문인데요
    (..)아래처럼 코드 작성해서 결과값 얻는건데

    제대로 된 결과가 나오면 0을
    제대로 된 결과가 아닐경우 1인듯 한데

    ('')/ 위에 집필하신거 보면.. 0,1,2,3, 등 다양한데
    저처럼 그냥 윈도우에서 도스창에서는 0,1 두가지만 나오도록
    정해진건가요?


    참고예제>
    Terminal Service 입력시 에러코드 0
    Terminal Service1 입력시 에러코드 1
    Terminal Service23232 입력시 에러코드 1


    ===============================================


    @echo off
    echo. 터미널서비스 사용 여부 확인 >> %COMPUTERNAME%-1.txt
    echo. >> %COMPUTERNAME%-1.txt
    net START | find "Terminal Service1" > NUL
    IF NOT ERRORLEVEL 1 GOTO TERMINAL-ACTIV >> %COMPUTERNAME%-1.txt
    IF ERRORLEVEL 1 IF NOT ERRORLEVEL 2 ECHO ☞ 터미날서비스를 사용하지않음 ---ERRORLEVEL 1 >> %COMPUTERNAME%-1.txt
    IF ERRORLEVEL 2 IF NOT ERRORLEVEL 3 ECHO ☞ 터미날서비스를 사용중이않음 ---ERRORLEVLE 2 >> %COMPUTERNAME%-1.txt
    IF ERRORLEVEL 2 IF NOT ERRORLEVEL 3 ECHO ☞ 터미날서비스를 사용중이않음 ---ERRORLEVLE 2 >> %COMPUTERNAME%-1.txt

    :EXIT
    echo EXIT 터미널 서비스 비사용~~~!!!
    PAUSE
    EXIT

    :TERMINAL-ACTIV
    echo.
    echo 터미널 서비스 사용~~~!!!
    • 2010.04.08 14:19
      댓글 주소 수정/삭제
      2행... echo. 터미널서비스 사용 여부 확인 >> %COMPUTERNAME%-1.txt
      화면에 나타나지 않음. 항상 %COMPUTERNAME%-1.txt 파일에 저장됨.
      3행도 마찬가지.
      4행에서... net START | find "Terminal Service1" > NUL
      왜 찾는 메시지가 "Terminal Service1"인지요? "Terminal Service"가 옳습니다.

      :EXIT
      echo EXIT 터미널 서비스 비사용~~~!!!
      PAUSE
      EXIT
      위에서 마지막에 붙은 exit 보다는
      goto :eof
      라고 하는 쪽이 더 낫습니다.
      exit의 경우 명령 프롬프트를 닫아 버립니다. 물론 그 배치파일 하나만 쓴다면 별 상관 없습니다만, 그다지 조흔 코드는 아닙니다.

      또한 종료코드에 관한 문제는 find 명령을 살펴보시기 바랍니다.
  6. 진만고양이
    2010.04.08 16:22
    네 일부러 COMPUTERNAME-1.TXT 에 저장하게 했습니다.


    4행은 일부러 Terminal Service1 1을 붙여봐서 에러코드가 뭐가 나오나 했더니 1이 나오더라고요 (에러코드가 뭐가나오나 궁금해서 실험해봄)


    여기서도 eof 를 쓰는군요

    프로그래밍 할때 end of file 해서 eof 쓰는데
    도스에서도 있는줄 몰랐습니다.


    댓글 이렇게 잘 달아주시니 정말 감사합니다 (^^)(__)
    • 2010.04.08 17:32
      댓글 주소 수정/삭제
      도스용 배치파일에서는 없습니다. 이 :eof 레이블은 윈도용에만 있는 가상의 레이블입니다.

들어가며

IF 명령은 FOR 명령과 함께 배치파일에서 지원하는 제어 명령이다. 또한 윈도XP는 도스의 그것보다 훨씬 강력한 기능을 제공하고 있다. 이때 if 명령은 가정문을 만들고, for 명령은 반복문을 만드는 데 쓰인다.

말뜻

IF는 말 그대로 "만약"이라는 뜻을 가지고 있다. 그러므로 이 명령어를 발견하면 영어를 읽듯이 읽어가면 된다.

  • 참고 : 프로그래을 짜다 보면 프로그래밍 언어의 어순은 영어의 그것과 아주 비슷함을 알 수 있다. 또한 수학의 수식이 배열되는 순서도 영어의 어순과 많이 닮아 있다.

if 기본 문법

명령줄에서 if 사용

if를 명령줄에서 쓸 수도 있지만, 주로 배치파일 안에서 쓰인다.

위 그림을 보면 분명히 명령줄에서 if 명령을 사용하고 있다. 처음 명령은 현재 디렉터리 아래에 aa 디렉터리가 존재하지 않는다면 Not found를 출력하는 명령이며, 둘째 명령은 c:\2 디렉터리가 존재하면 Found를 출력하는 명령이다.

기본 문법

명령줄에서 다음과 같이 입력하면 기본 사용법을 알 수 있다.

if /?

일단 if 명령은 조건문에서 나타나는 결과에 따라 명령어를 수행하게 됩니다. 이때 조건문은 다음과 같은 세 가지입니다.

  • 에러레벨문 : IF [NOT] ERRORLEVEL 숫자 명령어
  • 문자열 비교문 : IF [NOT] 문자열1==문자열2 명령어
  • 파일 존재 검사문 : IF [NOT] EXIST 파일이름 명령어

if 문은 위 세 가지 경우에 각 조건문이 참값을 가지면 뒤따르는 명령어를 실행시킵니다. 또한 세 가지 모두 "NOT"을 사용하여 조건문이 거짓인 경우에 명령어를 실행시킬 수도 있습니다. if, not, errorlevel, exist 등은 대/소문자를 가립니다. 대문자와 소문자를 구별하지 않으려면 /i 선택사항을 이용하면 됩니다. 다만 이 /i 선택사항은 명령 확장을 이용해야 한다. 다시 말해 도스의 if 명령과 호환성이 없다.

이 기본 문법에서는 명령 확장을 제외한 사항만 다룹니다.

말뜻

  • NOT은 영어 뜻 그대로 풀이하면 됩니다. 다시 말해 "~이 아니면"이라고 해석하면 됩니다.
  • ERRORLEVEL은 마지막으로 실행된 프로그램이 실행 결과로서 사용자에게 반환하는 마침 코드를 가리킵니다. 흔히 반환값이라고 부르며, 0부터 255 사이의 값을 가집니다. 일반적으로 "error level"이라고 띄어 쓰지만, 배치파일에서는 "errorlevel"이라고 자주 붙여 씁니다. 또한 ERRORLEVEL과 %ERRORLEVEL%은 서로 다르므로 주의해야 합니다. 마침코드가 뒤따르는 수보다 크거나 같으면 조건을 참으로 지정합니다.
  • 문자열은 "문자의 배열"이라는 뜻입니다. 쉽게 말하자면 화면에 보이는 글자의 모임 또는 묶음이거나, 기억장치에 저장된 문자의 모임 또는 묶음입니다. 명령줄에서 문자열은 <Enter>가 입력될 때까지 명령줄에 나타난 문자의 모임입니다. 또한 환경변수에 저장된 값은 기본적으로 문자열입니다. 이렇듯이 가리키는 대상에 따라 문자열은 조금씩 다르지만, 문자의 모임 또는 문자의 묶음이라는 점에서는 항상 같습니다.
  • 문자열의 비교 : 문자열을 비교할 때는 등호를 두 번 써서 비교합니다. 다시 말해 "문자열1==문자열2"와 같은 꼴로 비교하게 됩니다.
  • EXIST는 "존재한다"라는 뜻입니다. 이것은 항상 뒤따르는 파일이나 디렉터리가 존재하는지를 묻고, 존재하면 조건을 참으로 지정합니다.
  • ELSE는 "~이 아니면"이라는 뜻입니다. 이것은 앞서 나온 IF 명령이 조건을 거짓으로 지정할 경우에 실행하게 됩니다. IF 기본 명령에서는 다루지 않습니다.

예제

ERRORLEVEL문

마침 코드를 검사하여 알맞은 문장을 보여줍니다.

  1. @echo off
  2. rem 파일명 : GBackup1H2P.cmd
  3. rem 지은이 : koc2000/SALM
  4. rem 저작권 : GPL v3
  5.  
  6. rem 예제 11-1.
  7. rem 고스트 작업이 정상적으로 끝났는지를 알려준다.
  8.  
  9. rem 첫 번째 하드디스크 첫 번째 파티션에서
  10. rem 첫 번째 하드디스크 두 번째 파티션으로 백업한다.
  11. GHOST.exe -CLONE,MODE=PDUMP,SRC=1:1,DST=1:2\GHOST.GHO -Z9 -AUTO -SURE -RB
  12.  
  13. REM ERRORLEVEL 값이 1보다 작으면 NOERROR로 이동한다.
  14. IF NOT ERRORLEVEL 1 GOTO NOERROR
  15.     ECHO ##############################################
  16.     ECHO ##      백업 도중 오류가 발생했습니다.      ##
  17.     ECHO ##############################################
  18.     GOTO END
  19.  
  20. :NOERROR
  21.     ECHO ##############################################
  22.     ECHO ##    백업 작업을 정상적으로 마쳤습니다.    ##
  23.     ECHO ##############################################
  24.  
  25. :END
  26. REM 배치파일을 종료할 때 마침 코드를 되돌려준다.
  27. REM 이때 %ERRORLEVEL% 환경변수는 일종의 SET 명령 확장에 해당한다.
  28. EXIT /B %ERRORLEVEL%

시만텍 사의 프로그램은 오류가 발생하지 않으면 마침 코드로 0을 돌려주고, 오류가 발생하면 1 또는 1보다 큰 값을 돌려준다. 그것을 이용하여 고스트가 제대로 작업을 마쳤는지를 사용자에게 알려줄 수 있다.

  • 참고 : 위 GBackup1H2P.cmd 배치파일은 실패작이다. 배치파일을 실행할 환경을 고려하지 않고 작성한 탓에 도스에서도 윈도에서도 디스크를 백업한다는 본래 목적대로 실행이 되지 않는다. 물론 ERRORLEVEL문을 시험하는 예제라는 의미에서는 잘 작동한다.

문자열 비교문

if 명령을 이용하여 문자열을 비교할 수 있다. 도스에서는 문자열에 공백이 들어가는 경우가 없으나, 윈도에서는 공백이 들어갈 수도 있다.

앞서 만든 HelloWho2.cmd 파일을 참조하여 매개변수를 출력하는 배치파일을 만들었다.

  1. @ECHO OFF
  2. REM 파일명 : ViewPara.bat
  3. REM 지은이 : koc2000/SALM
  4. REM 저작권 : GPL v3
  5.  
  6. REM 예제 11-2.
  7. REM 매개변수를 한 줄에 하나씩 보여준다.
  8.  
  9. REM 가장 먼저 %0을 보여준다.
  10. ECHO %0
  11.  
  12. REM for 명령을 쓰지 않고 순환문을 만든다.
  13. :LOOP_START
  14.     REM %1 매개변수가 없으면 순환문을 끝낸다.
  15.     IF * == %1* GOTO :LOOP_END
  16.  
  17.     REM %1 매개변수를 출력한다.
  18.     ECHO %1
  19.  
  20.     REM %(N) 매개변수를 %(N-1) 매개변수로 자리 이동한다.
  21.     SHIFT
  22.  
  23.     GOTO :LOOP_START
  24. :LOOP_END
  25.  
  26. :END

GOTO 명령은 배치파일 내부에서 레이블이 있는 곳으로 CMD.EXE 명령줄을 옮기는 역할을 한다. 레이블은 앞에 콜론( : )을 붙여 구분하고 있다.

또한 SHIFT 명령은 %0부터 %9까지의 매개변수의 순서를 바꾸어 주는 역할을 한다. 다시 말해 %9는 %8이 되고, %8은 %7이 된다. 그렇게 하나씩 이동하며 %1은 %0이 된다. 또한 %9 바깥에 있던, 지금까지 표현하지 못했던, %10의 위치에 있던 값을 %9로 옮겨 준다.

ViewPara.bat 배치 파일은 윈도와 도스에서 모두 실행할 수 있으나, 실행 결과는 항상 같지 않다.


위는 윈도XP의 명령 프롬프트이며, 아래는 버추얼박스에서 도스 v6.22를 실행한 화면이다. 다른 경우는 모두 같지만, 따옴표로 묶인 부분을 처리하는 방법이 다르다. 다시 말해 윈도XP에서는 따옴표로 묶인 부분은 하나의 문자열로 보았지만, 도스에서는 따옴표는 무시하고 화이트스페이스(공백문자)로 나뉜 부분을 문자열로 보았다.

또한 이 문자열 비교문은 운영체제의 환경변수를 비교할 때도 쓸 수 있다.

파일 존재 검사문

배치파일은 작업에 앞서 파일이나 디렉터리가 존재하는지를 알아볼 수 있는 방법을 제공한다. 바로 "if exist"라는 구문이다.

  1. @ECHO OFF
  2. REM 파일명 : FindFile.cmd
  3. REM 지은이 : koc2000/SALM
  4. REM 저작권 : GPL v3
  5.  
  6. REM 예제 11-3.
  7. REM 명령줄에서 지정한 파일이 현재 경로에 있는지를 알려준다.
  8.  
  9. REM 판별 : %1이 없으면 도움말을 보여준다.
  10. IF * == %1* GOTO :ViewHelp
  11.  
  12. REM 판별 : %1이 있으면 그 파일이 있는지를 보여준다.
  13. IF EXIST %1 GOTO :Found
  14. ECHO File %1 was Not Found.
  15. ECHO.
  16. GOTO :END
  17.  
  18. :Found
  19. ECHO File %1 was Found.
  20. ECHO.
  21. GOTO :END
  22.  
  23. REM 도움말
  24. :ViewHelp
  25. ECHO FindFile v0.0.1
  26. ECHO Syntax : FindFile FileName
  27. ECHO.
  28.  
  29. :END

명령줄에서 매개변수로 파일명을 입력받아, 그 파일명에 해당하는 파일이 존재하는지를 알려준다.

 

다음 예고

IF 명령을 하나씩 짚어보자. (1)

이 글은 스프링노트에서 작성되었습니다.

'스크립트 > 배치파일' 카테고리의 다른 글

IF EXIST  (0) 2009.04.15
IF ERRORLEVEL에 쓰이는 종료코드  (12) 2009.04.14
IF 기본 설명  (6) 2009.04.09
배치파일에 매개변수 전달하기 2  (5) 2009.04.04
배치파일에 매개변수 전달하기  (0) 2009.04.01
배치파일 멈추기  (1) 2009.03.29
글쓴이는 koc/SALM입니다.
본문에 저작권에 대한 사항이 나타나지 않거나, 저작권이 BY-SA로 표기되어 있다면,
이 글은 GFDL로 공개한 글입니다.

댓글을 달아주세요:: 왕미친놈 욕은 해도 되지만, 근거없는 소리는 쓰지 말아 주세요.
BBCode 사용할 수 있습니다.

  1. 진만고양이
    2010.04.06 11:07
    9. REM 판별 : %1이 없으면 도움말을 보여준다.
    10. IF * == %1* GOTO :ViewHelp

    이부분의미가


    모든 매개변수입력값 (*)이 같으면(==) 매개변수 첫번째부터~마지막까지 (%1*)

    라는 의미가아닌가요??

    햇갈리네요.. %1 은 매개변수 하나를 의미하는걸로 아는데 *가 붙어있고


    이게 어떻게 %1 값이 없으면 Viewhelp 로 가라는 의미인지 자세한 설명좀 부탁드립니다 (^^)(__) 꾸벅

    (if * not exist 이런게있으면 ㅎㅎ)
    • 2010.04.06 12:27
      댓글 주소 수정/삭제
      흠 그렇게 생각할 수도 있겠네요. 일단 *만 있으면 확장자가 없는 파일이라는 뜻도 되니까요.
      하지만 배치파일에서 비교 구문은 기본적으로 "내용 비교"가 아닌 "문자열 비교"입니다. 다시 말해 if 구문에서 보이는 * 은 절대 "모든"으로 해석하지 않고, * 문자로 해석합니다.
      다만 %1의 내용이 * 또는 *.* 이라면 그 내용대로 "모든"이라는 뜻으로 해석합니다.
      IF * == %1* GOTO :ViewHelp
      위 구문의 뜻은 " * 문자와 %1의 내용에 * 문자를 붙인 것이 같으면 ViewHelp 레이블로 이동하라 "입니다. 이것을 다르게 말하면, "%1의 내용"이 공백이면 등호(==) 앞뒤의 내용이 같아지므로, "%1의 내용이 공백인지를 확인"하는 구문이 됩니다.
  2. 진만고양이
    2010.04.06 13:38
    이야 빠른 답변감사합니다 ㅏ(^^)(__)

    IF * == %1* GOTO :ViewHelp

    이말이
    만약 %1 이 공백이면

    * == (공백)* 이므로 즉 * == * 라는 것으로 이해하면 된다는거죠?


    산수로 치면
    (문자열) == (_문자열) -> (문자열) == (문자열) (<-- 이것은 아니지만 비유상..)

    * 는 문자열인데 공백은 문자로 쳐주지 않는건가요??
    • 2010.04.06 15:24
      댓글 주소 수정/삭제
      등호(==)의 앞뒤로 붙는 공백은 문자로 보지 않습니다. 아니 정확하게 말하면 명령어 해석기가 구문에서 필요한 띄어쓰기인지, 아니면 명령행 인수의 공백인지를 확인할 수 없습니다.
      게다가 이 경우는 공백이 아닙니다. 제가 설명을 잘못 했네요. 이 경우에는 공백이 아닌 NULL (아무것도 없다) 입니다.
      그러니 문제가 생기지는 않습니다.
  3. 진만고양이
    2010.04.07 11:18
    답변 감사합니다 ^^

    아..

    그럼 %1 에 인수가 없으면

    * == null * --> 즉 * == *

    (명렁어 해석기에서는 null을 무시한다라는말이라는거죠?)


카테고리

분류 전체보기 (1005)
스크립트 (22)
벌레와 팁 (126)
소프트웨어 (240)
하드웨어 (6)
이야기 (24)
말의 나무 (506)
미쳐보자 (22)
일기 (48)
아이폰 (10)

달력

«   2021/09   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30