들어가며
배치파일에서 좀 더 자세한 화면 출력과 배치파일의 가독성에 대해 알아보자.
화면 출력에서는 빈 줄과 ECHO와는 관계를 알게 되며, 배치파일의 가독성에서는 프로그래밍 일반에서 다루는 보기 좋은 코딩에 대해서 알게 됨을 목표로 하고 있다.
빈 줄 출력
배치파일에서 빈줄을 출력하는 일은 상당히 쉬우면서도 상당히 어렵다. 알기만 하면 아주 간단하지만, 모를 때는 갑갑하게 만드는 것이 "빈 줄 출력"이다.
첫 번째 시도
실험적인 코드를 만들어 보자.
- 소스 코드 : 예제 4
@echo off
rem 예제 4 : 빈 줄 출력 예제
rem 파일명 : exam04.bat
rem 지은이 : koc2000/SALM
rem 저작권 : GPL v3
echo 예제 4.
echo 이것은 빈 줄 출력 예제 4입니다.
echo 끝.
메모장을 열어서 위와 같은 코드를 입력하고 실행시켜 보기 바란다. 엔터를 쳐서 빈줄을 만든 만큼 빈 줄이 화면에 출력되는가?
<예제4 출력화면>
사실 이것은 그리 놀라운 일이 아니다.
지난 글에서 말한 ECHO 명령의 역할이 무엇인지를 생각하면 당연한 결과이다. ECHO OFF 는 "사용자에게 보이는 명령어 반향을 끈다"라는 뜻이었다. <Enter>를 쳐서 빈 줄을 만든 경우 사용자에게 보이는 명령어 반향이 공백 1줄(빈 줄)이었는데, 그 명령어 반향을 감추게 되면, <Enter>로써 만든 빈 줄이 사라지는 효과가 생긴다. 그렇다고 ECHO ON 을 하여 명령어 반향을 켜서 지난번의 그 지저분한 화면을 보기도 조금 그렇다. 빈대 잡으려고 초가 삼간을 태우는 격이다.
앞서 말했듯이 배치파일에서 빈 줄을 출력하는 일은 상당히 쉬우면서도 상당히 어렵다.
또 다른 시도
방금 만든 exam04.bat 파일을 다음과 같이 편집하고 exam04-1.bat라는 이름으로 저장하자.
- 소스 코드 : 예제 4
rem 예제 4-1 : 화면에 간단한 말을 출력한다.
rem 파일명 : exam04-1.bat
rem 지은이 : koc2000/SALM
rem 저작권 : GPL v3
echo 예제 4-1.
echo _
echo 이 프로그램은 화면 출력 예제 4-1입니다.
echo _
echo 끝.
실행해 보면, 아까와는 다른 결과가 나왔음을 알 수 있다. 위에서 주황색 바탕의 밑줄은 밑줄을 입력하라는 말이 아니라 스페이스 바를 한 번 눌러 빈칸을 만들라는 뜻이다. 빈칸은 하나가 아니라 훨씬 많아도 상관없다.
<예제4-1 출력화면>
이때 알 수 있는 것은 빈칸의 수가 아무리 많아도 같은 결과가 나온다는 점이다.
그렇다면 빈칸이라도 출력이 되어야 옳지 않을까?
이렇게 묻는 사람이 있다면 이렇게 답해 주겠다.
방금 말했다. 빈칸의 수가 아무리 많아도 같은 결과가 나온다.
이 말은 명령어 다음에 빈칸이 하나이든 백이든, 아니면 빈칸이 없든 같은 결과가 나온다는 뜻이다. 즉 ECHO 다음에, 다른 옵션이 없다면, 빈칸이 있든 없든 같은 의미를 가지게 된다는 말이다.
ECHO 명령의 기능은 (1) 메시지를 보여주거나 (2) 명령어 반향을 켜거나 끄고(기본값은 켠다), (3) ECHO 명령만 입력했을 때 반향 설정값을 보여준다. 이렇게 세 가지였다. 이 가운데 (3)번에 해당한다.
결국 ECHO 뒤에 빈칸을 넣어서 빈 줄을 입력하게 하는 방법도 실패다.
고전적인 방법
1980년대나 1990년대 초에 나온 컴퓨터 서적에서는 대개 아스키문자 255번을 이용하라고 하고 있다. 물론 나는 이 방법을 배우지는 않았다. 내가 컴퓨터 학원에 다닐 때는 좀 더 간단한 방법을 배웠기 때문이다.
고작 1백 년도 되지 않은 컴퓨터 역사에서 "고전"이 있을까마는 따지지 말자. "좀 더 오래된"이라는 의미를 부여하기 위해 쓴 말일 뿐이다.
우선 이 작업을 위해서는 exam04-1.bat 파일을 복사하여 exam04-2.bat 파일을 만든다. (복사 방법과 이름 바꾸는 방법은 모두 알고 있으리라 생각하고 생략하겠다. 모르면 댓글 남기기 바란다.)
명령 프롬프트에서 다음과 같이 입력한다.
edit exam04-2.bat
음, 뭔가 달라져 보이지 않는가?
<도스 에디터 화면>
빈 줄을 출력하려고 만든 줄로 이동하여 ECHO 뒤에 커서를 위치시키자. (위의 화면은 이미 이동한 화면이다.)
그 자리에서 <Alt>를 누른 상태에서 오른쪽 숫자판에서 2, 5, 5를 차례대로 누른 다음 키보드에서 손을 떼며 화면을 잘 살피기 바란다. (방금 했던 작업은 키보드를 이용하여 아스키문자 255번을 입력하는 작업이다.)
<도스 에디터 화면 : 255번 문자 입력 화면>
화면에는 아무것도 나타나지 않고, 그저 한 칸 오른쪽으로 옮겼다고 여겨질 뿐이다. 그러나 자신이 했던 일을 믿어라. 분명히 저기에는 아스키문자 255번이 입력되어 있다.
아래쪽으로 옮겨서 방금 그 작업을 다시 하자. 이때 주의할 점은 반드시 ECHO 뒤에 한 칸 공백을 둔 뒤에 아스키문자 255번을 입력해야 한다.
작업을 마쳤으면 저장하자. <Alt>를 한 번 누르면 왼쪽 상단의 [F/파일] 부분이 검게 바뀐다. 그 화면에서 F, S를 누른다. 다시 말해, <Alt>를 눌렀다 손을 떼고, F를 눌렀다가 손을 떼고, S를 눌렀다가 손을 떼면 저장이 된다.
저장도 마쳤으니 종료하자. 종료는 <Alt>, F, X 이다.
도스 상태에서 실행시켜 보자. 기대해도 좋다.
<예제4-2 출력화면>
드디어 성공했다.
그러나 아스키문자 255번을 누르기 위해서 해야 할 일이 너무 많고 번거롭다. 물론 아크로에디트를 비롯한 많은 문서 편집기가 "아스키코드"(아스키문자) 값을 지원해 주지만, 모르는 사람도 많다. 특히 윈도의 기본 문서 편집기인 메모장에서는 아스키문자 255번을 입력할 수 없다.
좀 더 새로운 방법
아스키문자 255번을 입력하여 빈줄을 나타내는 방법은 너무 번거로웠다. 그렇게 해서 알려진 방법이 바로 문서화되지 않은 방법이다. (MS 제품과 관련한 팁에는 많은 "문서화되지 않은" 방법이 존재한다. 심지어 일부 팁은 마이크로소프트 홈페이지에서도 활용하고 있다. 그러나 어디까지나 "문서화되지 않은" 방법은 해당 버전에서만 유효하며, 다음 버전에서는 언제라도 사라질 수 있음을 기억하자.)
exam04-1.bat 파일을 복사하여 exam04-3.bat 파일을 만든다.
- @echo off
rem 예제 4-3 : 화면에 간단한 말을 출력한다.
rem 파일명 : exam04-3.bat
rem 지은이 : koc2000/SALM
rem 저작권 : GPL v3
echo 예제 4-3.
echo.
echo 이 프로그램은 화면 출력 예제 4-3입니다.
echo.
echo 끝.
빨간 색으로 표시된 점( . )이 추가된 부분이다. 그 부분을 잘 보기 바란다.
실행하면 다음과 같다.
<예제4-3 출력화면>
- echo.
저 코드가 "빈 줄"을 출력하는 코드인 셈이다. 특이하게 ECHO 명령에 붙여서 써야 한다. 띄어쓰기를 하면? 직접 해보기를 바란다.
아주 간단하면서 쉬운 방법이다. 모를 때는 갑갑하게 만든 빈 줄 출력이지만, 알게 되면 어이 없을 정도로 쉽다. (물론 세상사가 대부분 그렇다. 오죽하면 "콜롬버스의 달걀"이라는 말이 생겼을까? 당시 "그냥 서쪽으로 가기만 하면 되는 쉬운 일이다."라고 주장하면서 콜럼버스의 업적을 폄하하는 사람들이 생겨나자, 콜럼버스가 자신이 신대륙을 발견한 일을 비유하기 위해 연회 자리에서 달걀 한쪽을 깨뜨려 식탁에 세운 일은 있지만, 콜럼버스가 최초로 한 일은 아니다. 그것은 당시 민간에서도 행해지던 놀이 가운데 하나였다고 한다.)
배치파일의 가독성
가독성이 왜 좋아야 할까? 그건 배치파일을 사람이 직접 눈으로 보고 해석할 수 있기 때문이다. 그래서 일부에서는 다른 사람이 내가 짠 배치파일을 고치면 엉뚱하게 동작하게 만들기도 하지만, 그것은 그다지 좋은 습관이 아니다. 그럴 경우 자신도 알아보기 힘들기 때문이다. (이럴 경우 실제 소스는 자신이 가지고, 남에게 보여도 되는 복잡한 소스를 컴퓨터에 설치해 두기도 하지만, 번거로운 방법이다.)
비단 배치파일뿐만 아니라 모든 프로그램 소스파일은 사람이 읽기 좋아야 고치기도 편하다. 물론 기계, 곧 컴퓨터에 맞추어 최적화를 시도해도 되지만, 그럴 경우 해당 부분을 모듈(흔히 함수 또는 서브함수)로 만들어 떼어낸 뒤 따로 설명을 붙이는 쪽이 낫다. 그래야 그 모듈은 신경쓰지 않고 전체 맥락에 집중할 수 있기 때문이다.
주석을 달고 가독성을 좋게 해야 하는 또 다른 이유로 배치파일은 한 번 만들어 두면 자주 고치지 않는다는 데 있다. 지금 만든 배치파일을 몇 달 뒤에 또는 몇 년 뒤에 알아볼 수 있을까? 장담할 수 없다. 나중에 고치려고 보면, 처음부터 다시 짜는 만큼 시간이 걸리기 마련이다. 주석을 달아두는 등 가독성을 좋게 해 두었다면 쉽고 빠르게 해결할 일인데 말이다.
가독성 높이기의 기본 : 주석 달기
잘 만들어졌지만, 배치파일 초보에게는 조금 파악하기 힘든 코드를 소개하겠다. 윈도98의 부팅 이미지에 있는 AutoExec.bat 파일의 일부이다.
-
@ECHO OFF
mshbios
set EXPAND=YES
SET DIRCMD=/O:N
set LglDrv=27 * 26 Z 25 Y 24 X 23 W 22 V 21 U 20 T 19 S 18 R 17 Q 16 P 15
set LglDrv=%LglDrv% O 14 N 13 M 12 L 11 K 10 J 9 I 8 H 7 G 6 F 5 E 4 D 3 C
cls
call setramd.bat %LglDrv%
set temp=c:\
set tmp=c:\
path=%RAMD%:\;a:\;%CDROM%:\
copy command.com %RAMD%:\ > NUL
set comspec=%RAMD%:\command.com
copy extract.exe %RAMD%:\ > NUL
copy readme.txt %RAMD%:\ > NUL
AutoExec.bat 파일의 첫 부분인 위 내용을 보고, 그것이 뜻하는 바를 곧바로 알 수 있다면 어느 정도 경지에 다다른 사람임에 틀림없다. 물론 저 뒷부분은 저렇게 붙어 있지 않다.
그런데 배치파일 초보가 위의 내용을 보고 각 행마다, 또는 여러 행이 어떤 의미를 가지는지 알 수 있을까? 그렇지 않으리라 생각한다.
그러면 알기 힘든 이유는 무엇일까?
도스의 명령어를 알더라도 주석이 없어서 알기 힘들다. 전체적으로 쉬운 명령어를 쓰고 있지만, SET 환경 변수를 이용하는 부분에서, 그것이 무슨 역할을 하는지 알기 힘들다. 이는 CALL 명령어에서도 마찬가지이다.
사람의 눈과 두뇌는 서로 떨어져 있으면 관련이 적다고 여기게 된다. 반대로 서로 붙어 있으면 관련이 좀 더 많다고 여기게 된다. 이런 원리를 생각한다면, 위의 코드는 서로 연관이 적은 코드까지 한데 뭉쳐 있는 셈이다. 앞서 말했듯이 저 부분까지만 저렇게 다닥다닥 붙어 있어서 읽기 힘들게 되어 있고, 뒷부분은 연관이 있는 줄끼리는 붙고, 서로 연관이 적은 곳은 빈 줄을 두어 나누고 있다. 빈 줄을 두면 화면에는 출력되지 않아도 사람이 보기에는 좋다.
조금 수정해 보았다.
-
@ECHO OFF
rem ====================================
rem 윈도98 설치 디스크
rem ====================================
rem 한글 바이오스 읽어오기
mshbios
rem 기본 환경 변수 설정
set EXPAND=YES
SET DIRCMD=/O:N
rem LglDrv 환경 변수 설정
rem 2행으로 설정한 이유는 한 줄에 적기보다 두 줄로 적어야 보기 좋고,
rem 명령행의 길이 제한 때문
set LglDrv=27 * 26 Z 25 Y 24 X 23 W 22 V 21 U 20 T 19 S 18 R 17 Q 16 P 15
set LglDrv=%LglDrv% O 14 N 13 M 12 L 11 K 10 J 9 I 8 H 7 G 6 F 5 E 4 D 3 C
rem 화면을 지우고, 램드라이브 설정 작업
cls
call setramd.bat %LglDrv%
rem 임시 디렉터리 변수 설정
set temp=c:\
set tmp=c:\
rem 실행경로 변수 설정
path=%RAMD%:\;a:\;%CDROM%:\
rem COMSPEC 환경 변수 설정 : 파일 복사 후 설정.
copy command.com %RAMD%:\ > NUL
set comspec=%RAMD%:\command.com
rem 작업을 위한 기본 파일 복사
copy extract.exe %RAMD%:\ > NUL
copy readme.txt %RAMD%:\ > NUL
아까보다야 낫지만 그래도 여전하다. 오히려 내용이 늘어서 보기 싫은 점도 있다.
왜? 앞서 말했듯이 코드가 너무 따닥따닥 붙어 있다. 그게 반드시 나쁘다는 말은 아니지만, 너무 붙어 있으면 배치파일 내용을 알기 힘들게 된다.
좀 더 보기 좋게 : 빈 줄 넣기
위의 경우에, 주석이 눈에 잘 들어오지 않는 이유가 코딩 속에 주석이 파묻혀 눈에 잘 띄지 않기 때문이다. 그럴 경우 몇 줄씩 관련 있는 부분을 묶고, 관련이 없는 부분과는 구별할 수 있게 줄 띄기를 하면 된다.
- @ECHO OFF
rem ====================================
rem 윈도98 설치 디스크
rem ====================================
-
- rem 한글 바이오스 읽어오기
mshbios
-
- rem 기본 환경 변수 설정
set EXPAND=YES
SET DIRCMD=/O:N
-
- rem LglDrv 환경 변수 설정 : 램드라이브를 위한 환경 변수이다.
rem 2행으로 설정한 이유
- rem 한 줄에 적기보다 두 줄로 적어야 보기 좋고,
rem 명령행의 길이 제한 때문 (128 글자)
set LglDrv=27 * 26 Z 25 Y 24 X 23 W 22 V 21 U 20 T 19 S 18 R 17 Q 16 P 15
set LglDrv=%LglDrv% O 14 N 13 M 12 L 11 K 10 J 9 I 8 H 7 G 6 F 5 E 4 D 3 C
-
- rem 화면을 지운다.
cls
-
- rem 램드라이브 설정 작업
- rem setramd.bat : 실제로 램드라이브를 설정해 주는 배치파일
call setramd.bat %LglDrv%
-
- rem 임시 디렉터리 환경 변수 설정
set temp=c:\
set tmp=c:\
rem 실행경로 환경 변수 설정
path=%RAMD%:\;a:\;%CDROM%:\
-
- rem COMSPEC 환경 변수 설정 : Command.com 파일 복사 후 설정.
copy command.com %RAMD%:\ > NUL
set comspec=%RAMD%:\command.com
rem 작업을 위한 기본 파일 복사
copy extract.exe %RAMD%:\ > NUL
copy readme.txt %RAMD%:\ > NUL
위와 같이 바꾸는 방법은 번거롭다고 여겨질 수도 있다. 하지만 배치파일의 특성상 그 자신이 어떤 일을 할 수도 있지만, 대부분 다른 프로그램에게 일을 시키는 "통로" 역할을 하게 된다. 다시 말해 배치파일 자체에서 일을 하기보다 다른 프로그램에게 일을 시키는 프로그램이다. 그것을 위해 환경을 설정하는 것이야말로 배치파일의 역할이다. 이게 스크립트 언어의 특징이다. (물론 자신이 직접 어떤 역할을 수행하는 스크립트 언어도 존재하지만, 거기에는 대부분 전제 조건이 붙어 있다.)
코드에도 격이 있다. : 들여쓰기
배치파일을 짜다 보면 중요한 코드와 덜 중요한 코드가 있을 수 있다. 또한 한데 묶어서 관리할 부분과 따로 떼어서 관리할 부분이 생기게 된다. 위의 코드도 마찬가지이다.
- rem 임시 디렉터리 환경 변수 설정
특히 위의 "rem 임시 디렉터리 환경 변수 설정"에서는 더욱 그러하다. 따로 떼어 생각할 부분이 아니기 때문이다. 이럴 경우 해결할 방법은 바로 들여쓰기이다.
앞서 ECHO 명령에서 했던 설명을 또 되살리자.
명령어 다음에, 다른 옵션이 없다면, 빈칸이 있든 없든 같은 의미를 가지게 된다.
여기에 추가하자.
명령어 앞에 다른 명령이 없다면, 빈칸이 있든 없든 같은 의미를 가지게 된다.
이 말은 곧 들여쓰기를 해도 실행 결과는 같다는 뜻이다.
이 말에 맞추어 위의 배치 파일을 고쳐 보자.
- @ECHO OFF
rem ====================================
rem 윈도98 설치 디스크
rem ====================================
rem 환경 설정
rem 한글 환경 설정
rem 한글 바이오스 읽어오기
mshbios
rem 기본 환경 변수 설정 1
set EXPAND=YES
SET DIRCMD=/O:N
rem 램드라이브를 위한 환경 설정
rem LglDrv 환경 변수 설정 : 램드라이브를 위한 환경 변수이다.
rem 2행으로 설정한 이유
rem 한 줄에 적기보다 두 줄로 적어야 보기 좋고,
rem 명령행의 길이 제한 때문 (128 글자)
set LglDrv=27 * 26 Z 25 Y 24 X 23 W 22 V 21 U 20 T 19 S 18 R 17 Q 16 P 15
set LglDrv=%LglDrv% O 14 N 13 M 12 L 11 K 10 J 9 I 8 H 7 G 6 F 5 E 4 D 3 C
rem 화면을 지운다.
cls
rem 램드라이브 설정 작업
rem 이 부분은 복잡하므로 다른 배치파일을 불러서 처리.
rem setramd.bat : 실제로 램드라이브를 설정해 주는 배치파일
rem 넘겨주는 명령행 인자 %LglDrv%
call setramd.bat %LglDrv%
rem 기본 환경 변수 설정 2
rem 임시 디렉터리 환경 변수 설정
set temp=c:\
set tmp=c:\
rem 실행경로 환경 변수 설정
path=%RAMD%:\;a:\;%CDROM%:\
rem COMSPEC 환경 변수 설정
rem COMSPEC 환경 변수는 명령어 해석기를 지정하는 역할을 한다.
rem Command.com 파일 복사 후 설정.
copy command.com %RAMD%:\ > NUL
set comspec=%RAMD%:\command.com
rem 작업을 위한 파일 복사
rem 압축 파일 작업용 extract.exe : CAB 파일의 압축을 푸는 프로그램
copy extract.exe %RAMD%:\ > NUL
rem 안내 문서 readme.txt : 안내문이 수록되어 있다.
copy readme.txt %RAMD%:\ > NUL
실제 실행에서는 처음에 만든 배치파일과 같게 동작한다.
요약
- ECHO를 이용해 화면에 빈 줄을 출력하는 방법과 배치파일을 사람이 읽기 좋게 만드는 법을 설명하였다.
-
기타
- 명령프롬프트에서 명령어 앞의 공백과 마지막 명령행 인자 및 옵션 뒤의 공백은 무시된다.
- 문서화되지 않은 방법은 불가피할 때만 써라.
다음 예고
배치파일을 잠시 멈추는 방법과 파라미터를 배치파일에 전달하는 방법에 대해 알아보자.
이 글은 스프링노트에서 작성되었습니다.