4.1 효율적인 배치 파일 작성 원칙
도스에서 배치 파일을 작성할 때에는 일반적인 도스명령(copy, dir, type등)과 함께 배치 파일 전용 명령(batch subcommand)을 사용함으로써 그 진가가 발휘된다 배치 파일 전용 명령은 일종의 간이 프로그래밍 언어로서 반복문 for, 조건문 if, 분기문 goto, 출력문 echo 등의 고급 언어가 가지고 있는 기초적인 특성만을 구비하고 있다 따라서 이러한 기능들만으로 고급스런 배치 파일을 작성하기는 사실 힘들다
그러나 약간의 외부 유틸리티나 숨겨진 기능을 잘 활용하면 고급 언어로 작성한 프로그램만이 처리할 수 있는 일들도 간단히 수행될 수 있다. 하지만 배치 파일 전용 명령은 다른 고급 언어에 비하여 몇 가지 약점을 가지고 있다
첫째, 배치 파일 명령중 출력 기능을 담당하는 것은 echo 명령인데, 그 기능이 줄(line) 단위로 이루어지기 때문에 홤녀상의 원하는 위치에 출력하는데 어려움이 있다 또한 문자의 출력 특성(attribute)이나 색(color)을 지정할 수 없으므로 다양한 출력 결과를 얻지 못한다 이러한 사항들은 ansi.sys 나 4도스를 사용함으로써 해결될 수 있기는 하나, 명령어가 기억하기 어렵게 구성되어 있어서 디버그(debugging)하기가 불편하다는 단점을 안고 있다
둘째, 변수(variable) 사용 능력이 미약하다 프로그래밍 언어는 변수를 사용함으로써 여러 가지 일들을 효율적이고 융통성 있게 처리한다 배치 파일에서는 변수 사용 능력이 미약하기 대문에 다른 고급 언어에 비하여 융통성이 적어지고 할 수 있는 일의 범위가 좁아지게 된다
셋째, 명령어 사용 형식이 단순하기 때문에 복잡한 구문을 작성하기 힘들다 예를 들어 if문의 경우 6가지 비교 형식을 제공하지만, if- then 이나 if - then - else 형식을 사용할 수 없기때문에 여러 개의 조건을 작성하기 힘들다
넷째 도스 명령어 처리기(command.com) 가 줄 단위로 처리하기 때문에, 실행 속도가 느리다 그러나 4도스를 사용하면 약간의 속도 향상을 볼 수 있다
다섯째 프로그램 구성에 확장성이 부족하다 즉, 다른 고급 언어의 루틴별 또는 모듈화되는 서브 프로그램을 작성해서 통합시키기가 힘들다
4.1.1 도스 배치 파일 프로그래밍
배치 파일 확장 명령어들을 잘 사용하려면 먼저 배치 파일에 대한 여러 가지 지식들이 필요하다 배치 파일에 대한 기초적인 내용은 지금가지 많이 다루어졌으므로 여기서는 간단히 언급만 하고 넘어가기로 한다
마지막으로 설명하고 넘어갈 것이 배치 파일을 설계할 때 생각해야 할 점 들이다. 결국 배치 파일을 작성한다는 것은 프로그래밍 언어로 프로그램을 작성하는 것과 다를 바가 없다 다라서 프로그램을 작성할 때의 일반 원칙들이 그대로 적용될 수 있다 여기서는 그 중 특히 배치 파일의 작성시 고려해야 할 점들을 알아보도록 하자
일반적인 프로그래밍 테크닉
1. echo off 의 사용
배치 파일의 실행될 때 echo off 를 제일 처음에 실행되게 한다 이렇게 해서 필요 없는 메시지가 출력되는 것을 막을 수 있다 또한 @문자를 이용해서 echo off 란 명령 자체도 화면에 출력되지 않게 한다 도스 명령어 상태의 디폴트는 항상 echo on이다
2. 확장 그래픽 문자(extended graphic character)의 사용
ibm-pc에서는 ascii문자 중 176-223번을 그래픽 문자로 사용하고 있다 이것을 잘 활용하면 보기 좋고 잘 정돈된 화면을 구성할 수 있다
3. 텍스트 파일의 사용
메뉴 화면 등에서 출력할 문장 많을 때는 메뉴 화면을 다른 텍스트 파일에 저장해 두었다가 type 명령을 써서 출력하는 것이 좋다 왜냐하면 배치 파일에서 echo 명령으로 출력하려고 하면 일단 명령 해석기를 거친 후 수행되기 때문에 그만큼 시간이 많이 걸리기 때문이다 단 별도의 텍스트 파일에 출력할 메시지를 저장시킬 때는 echo 명령을 빼야만 한다 왜냐하면 type 명령이 이 echo 명령까지 출력해 버리기 때문이다
4. 출력변경(output redirection)
copy 명령의 경우처럼 수행 후 자신의 메시지('1 file(s) copied 등)를 출력하는 명령들은 '존재하지 않는 부재 출력 장치'(null output device, nul)으로 출력 변경을 시키면 필요없는 메시지가 화면상에 나타나지 않게 된다
copy a:program1 b:program2 > nul
5. 사용하기 쉽게 작성한다
도스의 대체 매개변수(replaceable parameter)를 많이 사용해야 한다거나 너무 복잡한 메뉴 등은 만들지 않도록 하고 도움 화면이나 알기 쉬운 설명문등이 출력되게 한다
6. 배치 파일을 보기 좋게 작성한다
보통의 프로그램들과 마찬가지고 배치 파일로 요구에 따라 필요한 부분을 고칠 경우가 생길 수 있다 따라서 알기 쉽고 고치기 쉽게 작성하는 것이 중요하다 다음과 같은 주의 사항을 염두에 두면서 작성하는 게 좋을 것이다
=================================================================================
1. label 을 제외한 문장들은 들여쓰기(indentation)를 한다
2. rem 문을 이용하여 알기 쉽게 주석을 달아 놓는다
3. label을 쓸 때는 서브루틴의 내용을 눈치챌 수 있는 명칭을 사용한다
4. 필요 없는 goto 문의 사용을 최소한으로 줄인다
5. 공백을 띌 때는 space 키보다는 tab 키를 이용한다
6. 레이블명이 시작하는 각 서브루틴간에는 한 줄의 공백을 줘서 혼란스럽지 않게 한다
7. 도스의 상*하위 버전 호환성을 염두에 두면서 작성한다
=================================================================================
디버깅 테크닉
1. config.sys에 break = on 을 선언해 둔다
break 명령은 도스가 ctrl+c 가 눌려졌는지 검사하게 해준다 일반적으로 도스는 주변기기와 입출력을 수행할 때만 ctrl+c 가 눌려졌는지 검사하게 된다 하지만 break=on을 설정해 두면 ctrl+c 를 눌렀을 때 즉시 반응을 보이게 된다 따라서 이렇게 해 두면 배치 파일 수행중에 루틴이 잘못돼서 루프를 돈다거나 가끔 주변기기와의 입출력 없이 시스템이 정지했을 때라도 ctrl+c 를 눌러 도스로 돌아갈 수 있게 된다
2. 배치 파일이 원하는 대로 작동하지 않을 때는 echo off와 cls 명령을 없애고 프로그램을 수행시켜 본다 변수에 제대로 값이 들어가는지 확인할 수 있다
3. pause 명려을 사용하면 배치 파일을 실행 검사할 때, 중요한 부분에서 한 페이지씩 멈춰서 수행되는 과정을 살펴보기 편리하다
4.2 없으면 만들자
앞에서 이미 배치 파일의 약점에 대해서 살펴보았다 하지만 일반적인 배치 프로그램 리스트가 고급 언어로 작성한 소스 리스트처럼 보이게 할 수 있다 ms-dos 상태에서 지원되는 배치 명령어는 단일 형식이기 때문에 복합 구문을 형성하는데 문제가 많다 예를 들어 if 문의 경우 if - then 형식이나 if - then - else - then과 같은 복합 구문 형식을 지원하지 않는다 그러나 도스 상태에서도 이런 형식의 구문을 작성할 수 있는 방법이 있다
만약 이런 형식으로 배치 파일을 작성했다면, 언뜻 보기에 basic 언어로 작성한 리스트 같이 보일 것이다 사실 이 방법은 아무러 기능을 하지 않는 환경 변수를 이용해서 구문의 형식적인 요건만 갖추어 주는 것이기 때문이다 다음의 예제는 세 가지 반복 루프를 생성하는 것으로 앞서 설명한 방법을 이용하고 있다 또 도스 버전과의 호환성을 고려하였으며 4도스에서 사용하는 것과 같은 명령 분리자를 파이프 기호를 사용해서 처리해 주고 있다
command1 | command2 | command3 |............. | command n
파이프 기호를 명령 분리자로 이용하면서 주의해야 할 점은 마지막 명령어를 제외하고는 dos 표준 출력을 이용할 수 없게 된다는 것이다 또한 set 명령을 쓸 때는 파이프 기호 앞에 공간을 띄우지 말고 써야 한다 그렇지 않으면, 이후의 명령어까지도 set 으로 설정한 환경 변수의 문자열의 일부로 해석되기 때문이다 그러므로 set 문자열이 끝나는 바로 뒤에 파이프 기호를 넣어야 한다
그리고 if문 뒤에 goto 문을 사용하지 않고 if - then - else 형식을 사용하기 위해 임의의 환경변수 %then%, %else% 를 명령의 키워드로 사용하였다
또한 프로그램 리스트 작성시 탭을 이용해서 들여 쓰기를 적절히 잘 구사하면 보기 좋은 배치 파일 리스트를 만들 수 있을 것이다
그리고 리스트는 소문자나 대문자를 혼용해서 작성하는 방법을 사용해도 좋으며, 입력하기 귀찮다면 소문자나 대문자 어느 하나만으로 입력해도 상관은 없다 하지만 두 문자 형태를 혼용해서 사용하는 것이 시각적으로 눈에 잘 보이기 때문에 좋을 것이다 그리고 들여쓰기에서도 탭을 이용해서 들여쓰는 방법이 스페이서(space)나 공백 문자를 일일이 입력해서 칸을 들여쓰는 방법보다 명령어 처리기에서 해석되는 시간이 빠를 수 있다
왜냐하면, 배치 파일을 명령어 처리기가 해석하는 방법은 한 줄 단위로 읽어 들여서 처리하기 때문에 보통 8칸을 1탭으로 사용한 경우 이를 한 문자 단위로 처리하기 때문에 8자의 공백이 들어간 보다 읽어 들이는데 시간이 적게 걸린다 하지만 두 가지 방법에 있어서 커다란 속도 차이를 보이지는 않는다
또한 각각의 도스 버전과의 호환성을 유지하기 위해 몇 가지 안전장치를 해 두는 것이 바람직하다 예를 들어 @echo off를 도스 3.3 이전 버전에서는 @표시가 인정되지 않으므로 환경 변수를 이용해서 가변화 시켜 주면 편리하다 또 call 명령도 같은 방식으로 처리할 수 있다 즉, 도스 버전 3.3 이전과 이후의 큰 변화가 있었던 버전간의 호환성을 유지하기 위해서 특정 명령이나 변수를 상황에 따라 적절히 변화시킬 수 있도록 만드는 것이다
변수 버전 dos 3.3 이후 버전 dos 3.3 이전 버전
%@%echo off set @=@ set @=
%call% set call=call set call=%command% /c
<표 4-2> 호환성을 유지하는 방법
표에서 보듯이, %@%echo off 를 이용해서 배치 파일 서두를 시작하면, 도스 3.3이후 버전에서는 @echo off 로 해석되어 화면상에서 echo off 라는 명령이 나타나지 않는다 또한 도스 3.3 이전 버전에서는 'set @= '에 아무런 변수값이 대입되지 않았으므로 echo off 라는 문자열로 해석된다 그런데 call 명령을 아무렇게나 command /c 명령으로 대체하는 것은 바람직하지 않다
이 두 명령 사이에는 중요한 차이점이 있다 만약 배치 파일 실행 중에 다른 배치 파일을 호출하기 위해 call 명령을 사용하였는데, 호출된 배치 파일이 현재 환경을 바꾸어 놓았다면 변경된 환경이 call 명령이 종료되어 원래의 배치 파일로 돌아온 후에도 남아 있게 된다 하지만 command /c 명령은 환경에 대한 모든 변화는 배치 파일을 호출한 곳으로 돌아갈 때 사라져 버린다 이 점을 해결하기 위한 방법으로는 call 명령을 대체하는 변수로 도스 버전 3.3 이전과 이후에 사용될 2가지 변수를 따로 지정해 두는 것이다 즉, call 명령이 필요한 경우에는 %call%를 쓰고 command /c 명령이 필요할 때에는 %call% 라는 변수를 별도로 지정해서 사용하는 것이다
<3가지 종류의 루프를 돌리는 배치 예제>
=================================================================================
500p - 501p 중간생략
=================================================================================
예제에서 사용된 키워드(keyword) 주석은 배치 파일 처리하는 command.com에 아무런 의미를 갖지 않는 것으로 해석된다는 것을 이용한 것이다 이것들은 배치 파일 실행 중에 처리기가 환경 변수의 값을 구할 때에 의미가 없으므로 라인에서 제거된다 또한 한 줄에 복수의 명령어를 사용하는 것은 파이플 기호를 이용해서 마지막 이전 명령들이 도스 표준 출력을 하지 못하는 것은 아니다 따라서 한 명령이 표준 출력을 내고, 또 다음 명령이 도스 표준 입력을 받는 경우에는 문제가 발생한다 또한 한 명령이 리디렉션을 이용해서 출력 파일을 만든다면, 그 다음 명령은 수행되지 못할 것이다
goto 대신에 if-then-else 형식을 사용한 것은 한 줄에 복수 명령을 사용하기 위한 방법이다 이런 명령이 실행되려면 %then% 바로 뒤에는 %else% 행을 건너뛰는 goto 명령잉 뒤따라와야 한다 그러므로 goto 문을 아주 쓰지 말라는 얘기는 배치 파일에서 불가능하다 하지만 이런 형식을 이용하면 goto 명령을 직접 사용하는 것보다 구조화된 goto 문 형식을 만들 수 있다는 이점이 있다
배치 파일에서 선언되지 않은 %else% 구문을 이용함으로써 명령어 처리기는 이를 그냥 무의미한 키워드로 간주하지만 실제로는 복합적인 구문을 쉽게 형성할 수 있게 해준다 그 이유는 배치 파일이 한 줄 단위로 처리되기 때문이다 다음의 간단한 예를 보면 쉽게 알아챌 수 있을 것이다
rem 일반적인 if문의 사용구문을 이용한 방법으로 작성한 예
if '%1'=='which' goto which
if '%1'=='name' goto name
goto error
;which
this
that
theother
goto exit
;name
oh
kim
lee
goto exit
;error
echo you %1 is unknown variable .... try again
goto exit
;exit
<예제 4-27> 일반적인 if 문의 사용 예
위 일반적인 if 문의 형식을 키워드 변수를 이용하면 예에서 보다시피 16행에 이르는 긴 명령을 단 몇 줄로 짧게 줄일 수 있다
if '%1'=='which' %then% this | that | theother | goto exit
%else% if '%1'=='bar' %then% oh | kim | lee | goto exit
%else% goto error
;error
echo you %1 is unknown variable .... try again .....
goto exit
;exit
<예제 4-28> 예제의 4-7의 if 문을 키워드 변수로 함축시킨 방법
물론 이렇게 간단히 줄일 수 있는 것은 파이플 기호를 명령 분리자로서 사용할 수 있기 때문인데, 한 프로그램의 도스 표준 출력과 그 다음의 도스 표준 입력 사이에 서로 관련이 없음을 가정한 상태에서만 가능하다
위의 배치 파일 예제는 일 단위, 십 단위, 백 단위의 분리된 카운터를 제공함으로써 변수가 일정한 길이가 되면 멈추는 방법을 보여준 것이다. 하지만 여기서 사용된 키워드 변수 사용법과 명령 분리자의 이용은 부족한 배치 파일의 기능을 보다 확장해 주고, 고급 언어로 작성한 소스 리스트처럼 보이게 할 것이다 사용자의 아이디어와 머리를 짜낸다면 훨씬 잘 만든 배치 파일 리스트를 볼 수 있을 것이다
4.2.1 환경 변수를 이용한 서브루틴의 수행
도스의 배치 언어는 생각하기에 따라 상당히 다양하고 편리하게 사용할 수 있다 언뜻 보면 상당히 단순한 듯하면서도 막상 배치 파일을 작성하려고 달려들면 어려워 보이기도 한다 물론 원하는 기능과 목적에 부합되는 역할을 수행하도록 배치 파일을 작성하기는 쉽지 않을 것이다 하지만 평소에 자주 사용되는 기능별로 배치 파일을 서브루틴화 시켜 둔다거나 모듈화 시켜 두면, 필요할 때 빠르게 접목해서 사용할 수 있을 것이다
또한 이 방법은 프로그램 코드를 간결하게 만들 수 있으며, 디버깅하기도 훨씬 수월해진다 그리고 전체 리스트의 구성이 조직화될 수 있다는 장점도 가지고 있다 물론 배치 파일 내에서 이루어져야 하므로 서브루틴을 다루는데 goto 명령을 이용하는 것은 어쩔 수 없다 하지만 환경 변수를 goto 레이블명 변수명에 지정해 줌으로써 전체 서브루틴을 레이블명으로 지정할깨 발생할 수 있는 수정 작업을 하지 않게 만들 수 있다
그리고 고급 프로그래밍에서 서브루틴을 호출한 다음에 원래의 곳으로 값을 전달하거나 되돌아가기 위해 사용하는 명령인 return 을 변수명으로 이용해서 비슷하게 만들 수 있다 사용 형식은 다음과 같은 구조이므로 중간으로 생략하고 전체 형식만 살펴보도록 하자
set sub1 = 변수명
set return = main
;main
echo this program is main loop
goto %sub1%
;%sub1%
echo this is subroutine....
goto %return%
<환경 변수를 이용한 서브루인의 실행 방법>
goto %sub1% 명령은 서브루틴 %sub1%로 제어권을 이동시킨 후, 그곳의 명령들을 수행하다가 goto %return% 명령을 만나면 main 레이블로 이동해서 계속 명령을 수행하게 된다 왜냐하면 서브루틴 %sub1% 가 수행되기 전에 환경 변수 %return%의 값에 main이란 값을 지정했기 때문이다 따라서 서브루틴을 호출할 때마다 같은 리턴 레이블을 이용하면 원하는 만큼 서브루틴을 호출해서 편리하게 사용할 수 있다
4.2.2 도스에서 반복 처리를 쉽게 하는 방법
도스에서 여러개의 반복되는 파일 작업을 하다 보면, 이를 쉽게 처리할 수 있는 방법이 없을까 고민하게 되는데 4도스에서 와는 달리 도스에서는 이러한 작업이 쉽지만은 않을 것이다 이럴 때 배치 파일은 위력을 발휘하게 되는데, 정해진 범위와 횟수만큼 도스 명령이나 프로그램을 자동 실행시키도록 만들면 되는 것이다
여기서 소개하는 배치 파일의 명령 형식은 범위를 먼저 지정하고 명령어를 사용할 수 있다
loop ename=m,n command [p1 p2 p3 p4 p5]
ename 은 환경 변수이고 m은 시작하는 수, n은 끝나는 수이다 m과 n은 0이거나 0보다 큰 수여야 한다 또한 크기는 컴퓨터 메모리와 명령어 입력 행의 글자 수가 허용되는 한 제한이 없다 만약 n과 m의 숫자 개수가 같아야 하면 m앞에 0 을 덧붙여 처리할 수 있다 command에는 도스 프로그램이나 배치 파일, 도스 명령들이며 그 뒤에 5개의 선택 인자가 올 수 있다 m의 수가 클수록 명령어 실행은 오래 걸린다 아래 리스크에서 알 수 있듯이 %ename%의 형태처럼 도스 환경 변수를 명령어의 입력 변수로 사용할 수 있다 만약 명령어 없이 loop 배치 파일을 실행시키면 에러 메시지를 출력하고 종료된다 또한 명령어의 입력 변수로 loop.bat 자신을 사용해서도 안된다
먼저 배치 파일 리스트를 살펴보도록 하자
<반복 처리를 위한 배치 예제>
================================================================================
@echo off
rem 환경 변수가 초기화되었는지를 검사하고 초기화되었다면 count 레이블로 이동한다
if '%!%'=='%0' goto count
rem 명령행에 명령어가 존재하는지 확인하고 없으면 도움말을 보여준다
if '%4%'=='' goto help
rem 두번째 명령어 처리기 환경을 시작한다
if '%1'=='*' goto init
echo %4 %5 %6 %7 %8 %9 > $.bat
%comspec% /c %0 * %1 %2 %3
;init
rem 환경 변수를 초기화하는 루틴이다
set &=%4% | set n$=%4|set m$=%3|set #=%2|set !=%0
if not "%m$%'=='0' for %%a in (/%m$%z) do if '%%a'=='0'
set @=0
%!%
;count
rem 환경 변수 &를 이용해서 반복이 끝나는 수만큼의 과정을 하나씩 빼 나간다
rem 즉, for문으로 한번 반복할 때마다 플래그 &에 저장된 수가 감소된다
if '%&%'=='&' goto process
for %%a in (/%&%) do set &=%%a
;recurse
rem 변수를 이동해 가면서 loop.bat 을 계속 반복한다
set +=%1
if '%1'=='0' set +=%@%
call %!% %+%0 %+%1 %+%2 %+%3 %+%4 %+%5 %+%6 %+%7 %+%8 %+%9
shitf
if not '%1'=='' goto recurse
set &=%&%&
goto end
;process
set %#%=%1
if '%1'=='%m$' exit
shift
if not '%1'=='' goto process
goto end
; help
echo loop ename=m,n command [p1 p2 p3 p4 p5]
;end
================================================================================
이 배치 파일은 4단계의 과정을 거쳐서 수행되게 된다. 즉, 첫번째 단계는 처음부터 init 레이블까지로, $.bat 이란 임시 파일을 생성하는 과정이다 이 파일은 반복될 명령과 입력 변수가 저장하게 된다 그리고 loop.bat 이 다시 실행되는데, 이 때에는 새로운 command.com 환경에서 작업이 이루어지게 된다. 이때 asterisk(*)와 환경 변수, 반복 횟수를 지정하는 시작하는 수(m)의 입력 변수 및 끝나는 수의 입력 변수(n)들을 각각 첫번째, 두번째, 세번째 입력 변수로 사용하게 된다
이렇게 새로운 환경에서 배치 파일을 실행하도록 하는 이유는 배치 파일이 강제로 종료되어도 환경 영역에 지저분한 환경 변수들이 남아 있지 않도록 하기 위함이다
또한 환경 영역이 거의 남아 있지 않아 더이상 새로운 변수를 저장할 수 없는 상태라면 'out of environment space'라는 에러 메시지를 내보낸다 이럴 경우에는 %comspec% /e: 명령을 이용해서 환경 변수를 좀더 크게 설정하게 된다
두번째 단계는 새로운 명령어 처리기 환경에서 다시 호출된 loop.bat 이 실행되지만 * 때문에 init 레이블로 분기해서 시작하게 된다 이 과정에서는 여러 가지 환경 변수들을 초기화하고 다시 loop.bat 자신을 호출한다
세번째 단계는 리스트의 맨 처음에 있는 if문의 %!% 환경 변수와 %0이 같아지기 때문에 count 레이블로 이동해서 시작된다 이 과정에서는 끝나는 수(n) 만큼 loop.bat을 호출한다 즉, 끝나는 수의 숫자만큼 반복이 수행되는데, 각각의 반복 과정마다 & 환경 변수에서 숫자가 제거된다 따라서 &는 반복 계수를 카운트하는 플래그로 사용된 것이다
그리고 지정된 반복 횟수만큼 수행됐을 때는 recurse 레이블로 이동해서 변수를 shift 시키게 된다 즉, %1에 그 다음 변수인 %2를 할당하고, 환경 변수 +에서 시작하는 수를 할당받는다 그리고 다시 loop.bat가 호출된다
마지막 과정인 네번째 과정은 count 레이블로 진행해서 &변수는 모든 숫자가 제거되고 &만 남은 상태이므로 process 레이블로 제어권이 넘어가게 된다 이 단계에서는 shift 명려을 이용해서 모든 입력 변수를 차례차례 처리하는 순환 루핑이 이루어진다
이 순환의 시작은 #환경 변수에 첫 입력 변수 ename이 저장된다 그 다음에 첫번째 입력 변수가 시작하는 수인가를 확인한다 만약에 시작하는 수이면 변수 ^(원래 비어 있음)에 $를 저장하고 $.bat 을 호출한다 그런 식으로 시작하는 수에 도달하지 않았다면 아무것도 하지 않은 것이 되고, 그렇지 않으면 $.bat 를 호출하는 결과가 된다 그리고 $.bat에는 반복해서 실행할 명령과 입력 변수가 저장되게 된다
마찬가지로 shift 명령 때문에 첫 변수가 끝나는 수까지 다음 입력 변수로 사용된다 그리고 첫 변수가 끝나는 수에 이르면 exit 명령이 실행되어 첫단계에서 호출된 새로운 명령어 처리기 환경이 종료됨으로써 원래의 환경으로 돌아가게 된다 이것은 그 동안 사용한 모든 환경 변수들과 재귀 호출된 loop.bat 들이 자동적으로 지워지는 효과를 가져오게 된다
4.2.3 디버그를 이용한 배치 파일 유틸리티 작성
도스에 보면 debug 라는 프로그램이 있다 이것은 도스 프로그램이나 파일을 디버깅(debuging)할 때 사용하는 프로그램으로 간단히 실행 파일을 생성할 수 있도록 해준다 이 프로그램의 막강한 기능을 전부 소개할 수는 없지만 부족한 부분은 도스 메뉴얼을 참조하면 될 것이다 그럼 이 디버그를 이용해서 배치 파일에서 사용할 수 있는 작은 프로그램을 작성해 보자
대부분의 도스 프로그램은 "c", "assembler", "pascal" 등의 고급 언어로 작성되어 있다 하지만 여기서 그런 고급 언어로 작성하는 프로그램이 아니라 간단히 도스 프로그램에 포함된 디버그라는 유틸리티를 이용해서 입력을 바는 다거나 프린트를 해주는 간단한 팁을 스스로 만들어 보자는 것이다 따라서 여기서 소개하는 루틴은 디버거를 이용해서 만든 몇 바이트밖에 안되는 작은 프로그램이다
그럼 화면을 프린터로 프린트 시켜 주는 작은 유틸리티를 만들어 보자 도스 커맨드 라인에서 다음과 같이 입력해야 한다
c:>debug scrprint.com / 이 파일 이름은 당신이 이제 만들 파일 이름이다
file not found /디스크에 없는 파일이므로 일단은 에러 메세지를 낸다
-A 100 /offset(hexa)100 에서 프로그램 명령을 작성한다
5AFF;0100 int 5
5AFF;0102 mov ah,4c
5AFF;0104 int 21
- r cx / cx는 레지스터나 storage를 가리킨다
cx 0000
;6 / 이 숫자는 위의 0106-0100을 빼면 나온다 직접 수를 입력한다
-w / w 명령은 디스크에 파일을 저장하게 한다
writing 0006 bytes
-q / 디버그 프로그램을 빠져 나간다
<예제 4-29> 디버그를 이용해서 scrprint.com을 만드는 방법
이렇게 입력하고 dir로 해당 디렉토리를 보면 scrprint.com 이라는 파일이 6바이트 크기로 생성되어 있을 것이다 이 프로그램은 도스 텍스트 화면을 프린터로 바로 출력시키는 기능을 하게 된다 아주 작은 프로그램이므로 배치 파일에 삽입시켜 사용하면 간단히 출력할 수 있는 프로그램을 얻는 기분을 갖게 될 것이다
유사한 방법으로 reboot.com 이라는 파일을 만들어 보자
c:>debug reboot.com
file not found
-A 100
584B;0100 MOV AX, 40 /0472H 의 세그먼트 어드레스
584B;0103 MOV DS, AX /데이터 세그먼트에 주소를 할당한다
584B;0105 MOV AX, 1234 /1234 TELLS BOOTSTRAP TO "REBOOT"
584B;0103 MOV [72], AX /메모리에 값을 MOVE 시킨다
584B;0110 JMP FFFF:0 /부트스크랩 프로그램으로 JUMP한다
-R CX
CX 0000
-W
Writing 0010 bytes
-Q
<예제 4-30> 디버그를 이용해서 REBOOT.COM을 만드는 방법
Reboot.com은 bootstrap 프로그램을 이용한다 부트스트랩은 0472h의 메모리 위치를 검사하여 값 1234를 가지고 있는지 확인한다 즉, reboot.com 을 실행시키면 1234값을 정확한 메모리 위치에 집어넣고, jump 명령을 이용해서 bootstrap program으로 분기하여 시스템을 다시 부팅하게 만든다
그럼 이를 이용하여 config.sys를 에디트 하는 배치 파일을 만들어 보자 만약 randrive를 설치하고자 할 때 컨피그 파일을 고치고 효과를 내기 위해 다시 reboot 하여야 한다
그럼 다음의 배치 파일을 보자
<디버그로 만든 간단한 유틸리티를 이용해서 작성한 배치 파일>
echo off
if "%1"=="install" goto install_disk
if "%1"=="unload" goto unload_disk
goto done
;install_disk
rem config.sys에 device=ramdrive라는 엔트리를 추가함으로서 ram disk를 설치한다 %rem 는 램디스크의 크기를 결정한다 config.sys를 업데이트한 후 리부팅한다
if not exist config.sys goto add_entry
rem
rem ramdrive 를 포함한 config.sys 라인을 전부 지운다
rem
type config.sys | end /v "ramdrive" > config.new
del config.sys
rem
rem config.sys에 램드라이브 엔트리를 추가한다
rem
;add_entry
echo device=ramdrive.sys %2 >> config.new
ren config.new config.sys
reboot
goto done
;unload_disk
rem config.sys 로부터 램드라이브를 제거한 후 리부팅한다
rem
if not exist config.sys goto done
type config.sys | find v "ramdrive" > config.new
del config.sys
ren config.new config.sys
reboot
;done
이 배치 파일은 현재 사용중인 환경에 램드라이브가 설치되지 않았다면, 램드라이브를 추가하고 다시 리부팅해서 사용할 수 있게 해주는 프로그램이다 좀 더 응용하면 편리한 시스템 배치 파일을 만들 수 있을 것이다
또 배치 파일을 작성하다 보면 화살표 키를 사용자가 눌렀을 때 어떤 방향키가 눌렸는지 배치 파일에 알려줄 수 있는 방법이 필요한 경우가 많다. 이 값을 전달하는 getarrow.com 파일을 디버그로 한번 만들 수 있는데, 원리는 스캔 코드를 이용하는 것으로 위쪽과 아래쪽 화살표의 두 키(key)와 엔터키의 입력만을 받도록 만드는 것이다
<getarrow.com을 디버그로 작성하는 방법>
=================================================================================
c:>debug getarrow.com
file not found
-A 100
5B10:0100 mov ah, 8
5B10:0102 int 21
5B10:0104 cmp al, d
5B10:0106 jz 11a
5B10:0108 cmp al, 0
5B10:010A jnz 100
5B10:010C mov ah, 8
5B10:010E int 21
5B10:0110 cmp al, 48
5B10:0112 jz 11a
5B10:0114 cmp al, 50
5B10:0116 jz 11a
5B10:0118 jmp 100
5B10:011A mov ah, 4c
5B10:011C int 21
5B10:011E
-r cx
cx 0000
:1E
-W
Writing 001E bytes
-Q
c:>
=================================================================================
이제 이 getarrow.com 파일을 이용해서 메뉴를 선택하는 배치 파일을 하나 만들어 보자 메뉴의 형태는 상하 화살표만 필요로 하는 간단한 형태를 취하도록 하자
display directory
display dos version
display volume label
quit
<getarrow.com 을 이용해서 작성한 배치 메뉴의 화면>
그럼, 이를 이용한 배치 파일의 예제를 한번 살펴봄으로써 메뉴 시스템 작성시 효과적으로 getarrow.com 파일이 이용될 수 있다는 것을 볼 수 있을 것이다 물론 4도스 명령을 이용하면 훨씬 다양하게 구사할 수 있지만, getarrow.com 파일을 한번 만들어 두면 배치 파일 작성시 스캔 코드를 일일이 알아둘 필요가 없다는 편리함이 있다 그냥 위, 아래 화살표 키만을 사용하는 메뉴 배치 파일에 적절한 위체 삽입만 시켜 두면 되기 때문이다
<키 값을 알아내는 getarrow.com을 이용한 메뉴 배치 파일>
=================================================================================
@echo off
set current=dir
:loop
cls
rem echo 명령 뒤의 esc는 안시의 escapoe sequence 코드를 사용하면 된다
echo
echo
echo
if %current%==dir echo esc[1m display directory
if not %current%==dir echo esc[0m display directory
if %current%==ver echo esc[1m display dos version
if not %current%==ver echo esc[0m display dos version
if %current%==vol echo esc[1m volume label
if not %current%==vol echo esc[0m volume label
if %current%==quit echo esc[1m quit
if not %current%==quit echo esc[0m quit
getarrow
if errorlevel 80 goto down_arrow
if errorlevel 72 goto up_arrow
if %current%==dir dir
if %current%==ver ver
if %current%==vol vol
if %current%==quit goto end
pause > nul
goto loop
:up_arrow
if not %current%==dir goto up_ver
set current=quit
goto loop
:up_ver
if not %current%==ver goto up_vol
set currnet=dir
goto loop
:up_vol
if not %current%==vol goto up_quit
set current=ver
goto loop
:up_quit
set currnet=vol
goto loop
:down_arrow
if not %current%==dir goto down_ver
set currnet=ver
goto loop
:down_ver
if not %current%==ver goto down_vol
set currnet=vol
goto loop
:down_vol
if not %current%==vol goto down_quit
set currnet=quit
goto loop
:down_quit
set currnet=dir
goto loop
:end
echo esc[0m
set current=
=================================================================================
이 배치 파일은 화면에 흰색으로 메뉴를 표시하고, 현재 커서가 존재하는 위치의 메뉴는 밝은 색으로 빛날 것이다 안시를 이용해서 디자인에 신경 쓰지 않았기 때문에 그리 멋있는 상태가 아니지만 getarrow.com 파일을 이용해서 메뉴를 선택하는 방법을 이해하기에는 충분할 것이다




댓글을 달아 주세요