이곳은 백업 블로그 입니다. 현재 캐플이 활동 중인 블로그는 CAppleBlog.co.kr 입니다. 최신 정보들은 새로운 블로그에서 확인해 보세요. ^^

- 이곳은 기존 블로그들의 글을 한군데로 모아 놓은 백업 블로그입니다.

- 현재 링크는 대부분 올바르지 않으며 이러한 링크들은 모두 cappleblog.co.kr 로 이동합니다. (※ 링크 주의)

- 블로그와 커뮤니티는 서로 다른 공간입니다.(로그인을 따로 해야합니다.)

- 저는 윈티티(WinTT)이자 신비(ShinB)이며 캐플(CApple)입니다. 편한대로 불러주세요.

이 포스팅들은 저를 위한 기록입니다. 도스 시절 게임 한 번 돌릴려고 Config.sys 와 Autoexe.bat 파일을 편집하면서 시작했던 배치 파일인지라 체계적으로 배우지도 못하였고 다른 분들이 짜 놓으신 배치 파일이나 다른 툴들에서 짜놓은 배치 파일 보면서 공부하고 혼자 고민한 내용들입니다. 그러니 저에게 배치 파일에 대해 물어보셔도 여러분이 얻으실 수 있는 이득은 별로 없습니다.

 

작업 번호를 선택해야 하는 상황

많은 배치 파일 도구 속에서 행해야 할 작업 번호를 숫자로 선택해야만 하는 경우가 생깁니다. 제가 작성하는 배치 파일들 속에서도 그러한 경우가 많죠. 번호가 1부터 5까지 딱 떨어져 있다면 문제가 없지만 현재 목록을 뽑아오고 뽑아온 목록에 따라 번호 선택의 폭이 달라지면 어쩔 수 없이 현재 뽑아온 목록의 번호 안에서 사용자의 입력을 제한해야 합니다. 제가 짠 배치 파일들 중에 이를 가장 명확하게 보여주는 것이 Power BCD Editor 이죠.(해당 배치 파일에서 번호 목록을 가져오는 부분은 스누피님의 배치 파일에서 힌트를 얻었습니다.)

 

 

 

현재 부팅 메뉴 목록은 사용자마다 모두 다르기 때문에 현재 출력된 부팅 목록 외의 번호를 입력하면 적절히 이를 제한해야 할 필요가 생기게 됩니다. 즉, 위의 상황에서는 1,2,3,4,5 외의 입력은 무시해야 할 필요가 생기는 것이죠. 번호 목록을 가져오는 부분은 생략하고 이 상황에서 Power BCD Editor 0.1.1 에서 사용하던 작업 번호 검증 방식은 아래와 같습니다.

 

@echo off
setlocal

:Start
cls

:LOOP1
set /p NB1= 부팅 메뉴를 선택하세요. 번호 입력 (1~5) :

if not "%NB1%" gtr "0" goto LOOP1
if not "%NB1%" leq "5" goto LOOP1

goto ChoiceOK

:ChoiceOK
echo.
echo 도착했다!!
echo 당신이 입력한 값은 %NB1% 입니다.
pause
goto Start

 

이는 사용자가 입력한 값이 0 초과 5 이하 즉, 1~5 사이의 숫자를 입력하면 if 문을 무시하고 지나쳐서 goto ChoiceOK 를 만나게 되고 ChoiceOK 에 도착하게 되는 구조입니다. 그 외의 숫자나 문자를 입력하게 되면 if 에 의해 goto LOOP1 이 실행되어 다시 번호를 입력하는 곳으로 돌아가게 됩니다.

 

아무튼 이 방식은 if 의 비교 연산자를 통해 입력을 확인하는 방법입니다.

 

 

 

 

그런데 이 망할놈의 비교 연산자에는 한 가지 문제가 있습니다. 1r 과 같이 숫자로 시작하고 뒤에 문자가 결합된 값이 발생할 경우에는 어떻게 처리될까요? 불행히도 1r 을 5 보다 작은 값로 인식됩니다. 그래서 무사히 if 구문을 통과하게 됩니다.

 

 

 

도착한 곳에서 사용자가 입력한 값을 토대로 명령을 내리게 된다면 명령은 당연히 오류가 발생할 수 밖에 없습니다. 즉, 오류를 미연에 방지하기 위한 번호 확인에 최종적으로 실패한 것이죠. 그래서 이러한 오타도 염두하여 좀 더 강력하게 작업 번호를 검증해야 할 필요가 Power BCD Editor 0.2.0 에서 생겼습니다.(1 r 과 같이 입력하는 부분이 생긴 것이죠. 여기저기 작업들이 비슷하다보니 헷갈려서 다른 곳에서 이렇게 입력할 가능성이 생긴겁니다.) 이 문제를 가지고 여러가지로 생각해 보다가 화장실에서 힘을 주는 순간!!! for 구문이 떠 오르더군요.

 

"끄으으으으응~~~~! 헉!! 그래 for 가 있었지? 이런 무식한 놈;;"

 

아래는 그렇게해서 변경된 Power BCD Editor 0.2.0 버전에서 사용하는 작업 번호 검증 구문입니다.

 

@echo off
setlocal

:Start
cls

:LOOP1
set /p NB1= 부팅 메뉴를 선택하세요. 번호 입력 (1~5) :

for /L %%a in (1,1,5) do (
          if "%NB1%" == "%%a" goto ChoiceOK
)

goto LOOP1

:ChoiceOK
echo.
echo 도착했다!!
echo 당신이 입력한 값은 %NB1% 입니다.
pause
goto Start

 

for /L 은 단계별로 증가/감소하는 일련의 숫자를 변수의 집합으로 정의할 때 쓰입니다. 즉, for /L 변수 in (시작,증가값,끝) 이며 for /L %%a in (1,1,5) 는 1,2,3,4,5 를 차례로 %%a 변수로 할당한다는 뜻이 됩니다. (5,-1,1) 은 5,4,3,2,1 이 되겠죠?

 

 

 

사용자가 입력한 %NB1% 변수를 차례로 %%a 변수와 비교하여 "%NB1%" == "%%a" 로 사용자가 입력한 값이 1,2,3,4,5 중에 하나라면 ChoiceOK 로 가게되고 이 외의 값이라면 즉, for 에서 설정한 집합의 마지막까지 동일한 경우를 찾지 못하면 for 구문은 종료되고 goto LOOP1 을 만나 다시 번호를 입력하는 단계로 가게 되는 것으로 바뀐 것입니다.

 

즉, 비교 연산자로 "~ 에서 ~ 까지" 라는 구조를 버리고 설정한 값 안에서 오직 "동일"한 값을 만난 경우에만 명령을 실행하는 구조로 바뀐 것이죠. 어차피 예제로 든 상황에서 우리가 확인해야 할 값은 숫자 밖에 없으니까요.

 

 

이렇게 구문을 바꿀 경우 1r 과 같은 오타가 발생하여도(또는 그렇게 쓸 부분이 아닌데 그렇게 썼을 경우에) 검증 부분을 통과해버리는 상황을 막을 수 있습니다. 그래서 Power BCD Editor 0.2.0 에서는 전체적으로 이 구조가 사용되고 있습니다.

 

 

p.s 근데 내가 이 포스팅을 왜 썼지... ㅡㅡ;;

 


댓글을 달아 주세요