Useful Solutions2014. 9. 26. 09:39

오랫만에 구관이 명관 시리즈를 업데이트해봅니다. 이번 아티클은 작지만 확실히 유용한 팁 하나를 소개해볼까 합니다. 배치 파일을 작성하고 배포할 때 가장 큰 문제가 되는 것이, 배치 파일이 의도하지 않은 디렉터리 경로 상에서 실행된다는 점일 것입니다.

 

 

예를 들면 배치 파일을 명령어나 다른 프로그램을 이용하여 실행하면 배치 파일이 있는 경로가 아닌 호출한 프로그램의 현재 디렉터리 경로 위에서 실행되어서 문제가 될 때가 있습니다. 물론 배치 파일의 이런 특성을 활용해야 하는 경우도 있겠습니다만, 보통은 배치 파일을 실행할 때 정확히 해당 경로 상에서 어떤 작업을 하도록 의도한 것이 많으므로 이런 특성은 불편할 수 있습니다.

이 문제를 수정하려면 배치 파일의 경로를 항상 정확하게 알 수 있어야 하는데, 이럴 때 %~dp0 환경 변수를 사용하면 쉽게 문제를 해결할 수 있습니다. 하지만 무작정 cd 명령을 사용하면 배치파일이 끝나고 난 다음에 디렉터리 위치가 원래대로 돌아오지 않는 문제가 남습니다.

이런 문제를 해결하기 위하여, 새로 작성하는 배치 파일의 시작과 끝을 아래의 코드처럼 작성하도록 하면 편리할 것입니다.
@echo off
pushd "%~dp0"

rem 여기에 배치 파일 본문을 작성합니다.

:exit
popd
@echo on


 

내용은 단순합니다. 실행하는 명령줄이 보이지 않게 @echo off로 감추고, pushd 명령을 사용하여 스택에 현재 디렉터리 경로를 push하고 새 위치로 이동한 다음 원하는 일을 하는 것입니다. 그리고 나중에 종료할 때에는 popd 명령을 사용하여 직전에 저장한 디렉터리 경로를 꺼내와 그 위치로 다시 이동하고 @echo on으로 (심미성을 위하여 @echo on이라고 썼습니다.) echo 상태를 복원합니다. 여기서 :exit 라벨은 프로그램 내에서 탈출 조건을 만났을 때 편리하게 활용할 수 있도록 하기 위한 것입니다.

위의 예제를 활용하면 다음과 같이 응용할 수 있습니다.

@echo off
pushd "%~dp0"


if not exist %windir%\system32\runas.exe. (
    echo RUNAS.EXE 프로그램을 찾을 수 없습니다.
    pause
    goto exit
)

for /r "%~dp0" %%v in (test.cmd) do (
    if exist "%%v" (
        echo %%v 진행 중...
        call "%%v"
        rem 다른 배치 파일을 호출하고나면 echo on 상태가 되므로 다시 @echo off로 꺼줍니다.
        @echo off
    )
)

:exit
popd
@echo on


 

위와 같이 활용한다면 배치 파일을 어디서 실행하든 원하는 경로로 들어갔다가 다시 쉽게 원래 위치로 되돌아올 수 있으므로 일반 프로그램처럼 배치 파일을 작성하는 것이 좀 더 쉬워집니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2009. 8. 31. 18:14

요즈음 빌드 자동화 기능을 제공하는 프레임워크와 도구들이 굉장히 많이 늘었습니다. 각기 다양한 특색이 있고 장점이 존재하지만 가끔 이와 같은 도구들의 힘을 빌리지 않고 이와 유사한 기능을 작성할 필요가 있는 경우가 있습니다. 이럴 때 한치의 손색이 없는 도구가 하나 있는데 그것이 바로 명령줄 인터프리터가 직접 처리하는 Batch File입니다. 생각보다 Batch File의 능력은 다양합니다. :-)

Note: 이 Article은 Windows XP 이상의 운영 체제에 내장되어있는 Command Interpreter에 대하여 서술한 것으로 Windows 2000, Windows 9x (Microsoft DOS 7.x), Microsoft DOS 6.x 이하에는 맞지 않는 내용도 포함되어있습니다. 착오 없으시기 바랍니다. 더불어, 다른 DOS (예: 4DOS, DR-DOS 등)에서 자체적으로 제공하는 내장 Command Interpreter의 경우 자체 내장되어있는 도움말을 참고하여야 할 수 있습니다.

문자열과 숫자의 비교

일부러 찾아보고 활용해보지 않았을 뿐이지 배치 파일에도 if와 else 구문을 그대로 사용할 수 있습니다. 물론 진짜 제대로된 프로그래밍 언어에서처럼 완벽한 논리 연산을 구현한 것은 아닙니다만 배치 파일을 사용하려는 목적에는 알맞을 수 있는 기능들을 빠짐없이 훌륭하게 구현하고 있습니다.

간단한 if / else 명령문 하나를 입력해 보겠습니다.

if test equ test (echo same string) else (echo different string)
if test neq Test (echo different string) else (echo same string)

위의 명령문을 실행하면 same string 이라는 문자열이 나타납니다. 여기서 test는 보통의 DOS 명령에서 요구하는 파일 경로에 대한 것이 아니라 순수한 문자열이나 숫자가 됩니다. 그리고 equ가 동일성 여부를 판정하는 연산자가 됩니다. 만약 같지 않음을 비교하려면 neq 연산자를 대신 사용하시면 됩니다. 나머지는 보시는 그대로 괄호로 명령문이 묶인 것을 볼 수 있습니다. 괄호를 입력하지 않으면 참 조건시 실행될 echo 문의 나머지 뒷쪽 부분들이 전부 echo 명령에 대한 매개 변수로 지정되기 때문에 이를 구분한 것입니다. 그러면 이번엔 아래와 같이 특정 문자를 대문자로 바꿔서 명령을 수행해보도록 하겠습니다.

if Test equ test (echo same string) else (echo different string)

위의 명령문을 실행하면 기대한 대로 different string 이라는 문자열이 나타납니다. 여기에 부수적으로, 대/소문자 구분을 무시하여 비교하는 명령을 수행해보기로 하겠습니다.

if /i Test equ test (echo same string) else (echo different string)

/i 스위치가 대/소문자 구분을 무시하도록 지정한 것으로 결과는 기대한 대로 same string 이라는 문자열이 될 것입니다. 그렇다면 이 결과에 부정 연산자를 취하여 결과를 뒤집는 것도 가능할까요? 방법은 간단합니다.

if /i not Test equ test (echo same string) else (echo different string)

/i 스위치가 없다면 if 문 바로 다음 앞에, /i 스위치가 있다면 /i 스위치 바로 다음 앞에 not 연산자를 지정하여 Test equ test 식에 대한 결과를 반전 연산자를 통하여 뒤집게 되므로 기대하였던대로 different string 이라는 문자열이 대신 출력될 것입니다.

그렇다면 같음을 비교하는 것 말고 문자열과 숫자의 크고 작음을 비교하는 것도 가능할까요? 이번엔 아래와 같이 명령어를 넣어보겠습니다.

if test lss tess (echo a) else (echo b)
if test lss test (echo a) else (echo b)
if test lss tesu (echo a) else (echo b)

위의 명령들에 대한 수행 결과는 각각 b, b, a 가 됩니다. 프로그래밍 코드 식으로 풀이해보면 compare("test", x) < 0 에 비유할 수 있으며 앞서 본 tess와 test는 test보다 앞서거나 동일하므로 else 절의 문장이 수행된 것입니다. 반면 tesu는 test보다 뒤에 오는 단어이므로 if 절의 문장이 수행된 것입니다.

만약 위의 예제에서 lss 대신 leq를 선택한다면 test와 test를 비교하는 부분에서 b 대신 a가 선택 될 것입니다. 프로그래밍 코드 식으로 풀이한다면 compare("test", "test") <= 0 가 되므로 참에 해당되기 때문입니다. 더불어, 위의 연산 식 역시 /i 스위치와 not 연산자의 적용을 그대로 유지할 수 있으므로 이들 옵션이 위의 식에 대하여 끼치는 영향은 동일합니다.

프로그래밍 코드 식으로 compare("test", x) > 0 연산에 해당되는 것은 gtr 연산자이며, compare("test", x) >= 0 연산에 해당되는 것은 geq 연산자가 될 것입니다.

지금 이야기한 기능들은 단독으로 사용될 때 보다는 배치 파일에 주어지는 매개 변수들이나 미리 설정된 환경 변수들의 값을 다루는 데에 더 요긴하게 사용됩니다.

다음 Chapter에서는 if / else 문을 이용하여 파일이나 디렉터리의 존재 여부를 파악하는 방법, 환경 변수의 정의 여부를 파악하고 그 값을 파악하는 방법, 프로그램이나 배치 파일의 수행 결과를 if 문으로 파악하는 방법 등을 다뤄보기로 하겠습니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. DOS 6 책으로 배치 파일 프로그래밍을 배웠을 때가 생각납니다..ㅋㅋ

    2009.09.01 17:24 [ ADDR : EDIT/ DEL : REPLY ]
    • DOS를 사용하지는 않지만 기본 컨셉 자체는 Windows 7이 나오는 이 시점에도 여전히 유효한것 같아서 공부할 겸 올려보려고 합니다. :-)

      2009.09.03 00:44 [ ADDR : EDIT/ DEL ]