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