콘텐츠로 건너뛰기
Home » (Dos) 명령줄에서 For 사용하기

(Dos) 명령줄에서 For 사용하기

나는 vim을 소스에서 mingw-w64로 컴파일하여 사용중이다. vim을 컴파일한 결과물은 소스 디렉토리에 생성된다. 이 파일을 원래 vim 이 있던 자리로 복사하는 과정은 꽤나 귀찮을 수 있다. 물론 원래 vim.exe 파일이 있던 자리에만 복사하면 되지 그게 무슨 문제냐…고 할 수 있지만 Git 디렉토리 내에도 vim 이 있고 msys 내에도 vim 이 있기 때문에 좀 곤란하다. 한방에 할 수 있는 방법이 없을까?
물론 수동으로 해당 위치들을 파이썬 스크립트 같은 곳에 지정해놓고 복사하는 코드를 짜는 것도 방법이겠다.

from pathlib import Path
import subprocess
from shutil import copyfile
def main():
    paths = [Path(x).parent for x in subprocess.check_output(['where', 'vim'],
        universal_newlines=True).split('\n')][1:]
    exes = ('vim.exe', 'gvim.exe')
    for e in exes:
        if (Path(__file__).parent / e).exists():
            print("FILE {} IS CHECKED, START COPYING".format(e))
            for p in paths:
                if p == Path(__file__).parent:
                    continue
                try:
                    print("  COPYING {} TO {}".format(e, str(p)))
                    copyfile(str(e), str(p / e))
                except:
                    print("    ERROR DURING COPYING {} TO {}".format(e, str(p)))
if __name__ == '__main__':
    main()

근데 이건 너무 귀찮으니까 (아니, 이 시점에 이미 다 짜두었는데?) 다음과 같이 도스의 FOR 명령을 쓸 수 있다. 사실 DOS 역시 FOR 문을 지원하고 있는데, 보통 쉘에서 반복문은 한 번 알아두면 요긴하게 쓸 데가 많긴하다.

FOR /F "skip=1 delims=" %G IN ('where vim') DO COPY /Y vim.exe"%~dpG"

몇 가지 설명을 곁들여 보자. 자세한 내용은 명령 프롬프트 상에서 HELP FOR를 입력해서 볼 수 있다.

  1. /F 옵션은 파일(집합) 및 문자열이나 명령의 결과의 각 행에 대해서 특정 명령을 반복합니다.
  2. /F 뒤에는 옵션이 옵니다. 각 옵션은 따옴표 안에 들어가며 공백으로 구분합니다.
  3. skip=1은 첫번째 행을 무시한다는 의미입니다. (왜냐면 첫번째 행은 현재 디렉토리가 될거기 때문에 파일을 자기 자신으로 복사할 수 없습니다.)
  4. delims=는 각 행의 기본 구분값(공백이나 탭)을 무시한다는 의미입니다. 엄청 귀찮게도 "Program Files (x86)"과 같이 공백이 들어간 디렉토리명을 시스템이 강제하는 병신같은 윈도우….
  5. %G는 각 행을 받을 변수입니다. 만약 이 명령이 배치파일 내에서 사용된다면 %%G이라고 두번 써야 합니다.
  6. IN 다음에는 집합이 옵니다. 여기서는 ('where vim')이라고 %PATH%에 포함된 vim 실행파일 경로를 찾습니다.
  7. DO 다음에는 실행할 명령입니다.
  8. %~dpG%G를 확장합니다. 드라이브이름과 경로로 확장한다는 의미입니다. 이 때 디렉토리 안에 공백이 들어간 병신같은 시스템이므로 이를 따옴표로 둘러싸야 한 덩어리의 경로로 인식됨에 주의합니다.

따라서 최종적으로 생성한 deplay.bat 의 내용은 다음과 같다.

@echo off
FOR /F "skip=1 delims=" %%G IN ('where vim') DO COPY /Y vim.exe "%%~dpG"
FOR /F "skip=1 delims=" %%G IN ('where vim') DO COPY /Y gvim.exe "%%~dpG"
echo on