요약
탐색기는 더블클릭한 프로그램의 현재 디렉터리를 맞춰 주지만, 배치 파일은 그렇게 하지 않습니다.
마이크로소프트의 레이먼드 첸이 블로그 The Old New Thing에서 고객 사례를 소개했습니다. 배치 파일로 실행하면 오류가 나고 더블클릭하면 잘 돌아가는 프로그램을 보고, 그는 현재 디렉터리(프로그램이 상대 경로의 기준으로 삼는 폴더)부터 의심했습니다.
왜 중요한가
- 더블클릭을 배치 파일로 옮기려면 실행 명령뿐 아니라 실행 환경까지 똑같이 맞춰야 합니다.
- 부가 파일을 현재 디렉터리에서 찾는 프로그램은 어떻게 실행하느냐에 따라 성공할 수도, 실패할 수도 있습니다.
핵심 내용
- 탐색기는 더블클릭한 항목이 들어 있는 폴더를 프로그램의 현재 디렉터리로 정합니다.
- 이 동작은 부가 파일을 현재 디렉터리에서 찾는 프로그램을 배려한 것입니다.
- 고객의 배치 파일은 프로그램을 전체 경로로 실행했지만 현재 디렉터리는 바꾸지 않았습니다.
- 고객은
pushd로 프로그램 폴더로 옮겨 실행하고popd로 되돌아오게 해 문제를 해결했습니다. - 첸은 다음 점검 대상으로
App Paths레지스트리 항목이PATH에 폴더를 추가하는지를 꼽았습니다.
HN 반응
- 드라이브마다 현재 디렉터리를 따로 두는 윈도 동작을 두고, 유용하다는 쪽과 보이지 않는 상태라 위험하다는 쪽이 갈렸습니다.
- 문서를 열면 그 폴더가 현재 디렉터리가 되므로 악성 DLL이 로드될 수 있다는 우려에, 검색 순서상 우선하지 않는다는 반론이 나왔습니다.
드라이브 문자가 있으면 DOS/윈도 명령 프롬프트(파워셸은 묻지 마세요)에서 쓸 수 있는 멋진 기능이 하나 있습니다. 문자마다 각자 "현재 디렉터리"를 가질 수 있다는 점입니다.
ffmpeg.exe가
C:\Program Files\FFMpeg\bin에 있고, 원본 영상이D:\SourceVideos에 있고, 이걸 ffmpeg로 처리해서E:\Output에 출력하고 싶다고 해봅시다. 이렇게 하면 됩니다.C:(C: 드라이브로 이동)cd "C:\Program Files\FFMpeg\bin"E:(E:\ 드라이브로 이동)cd D:\SourceVideos(현재 위치는 계속 E:\이지만, D:의 "현재 디렉터리"는 바뀐 상태입니다.)cd Output(E:\Output으로 들어감)이제
C:ffmpeg.exe -i D:scene1.mp4 output-scene1.mp4라고 하면윈도가 각 드라이브 문자의 "현재" 디렉터리에서 파일을 찾아 줍니다.
저는 이게 좋다고 생각하지 않아요. 끔찍하다고 봅니다. 눈에 안 보이는 상태는 정말 질색이에요.
현재 작업 디렉터리에 의존하는 순간마다 그것도 눈에 안 보이는 상태죠. 드라이브 문자마다 따로 상태를 들고 있지 않더라도요.
$PATH나 다른 환경 변수도 마찬가지입니다. cron을 쓰다 보면 호되게 겪게 되죠. 저는 cron 스크립트에서는 전부 전체 경로를 씁니다. cron 환경이 평소 작업 환경이나 루트 셸의 환경과 어떻게 다른지 따져 보는 게 너무 번거롭거든요.
저는 조회만 할 수 있다면 괜찮을 것 같아요. 그 상태를 단지 옮겨 다니는 것 말고 직접 다룰 방법이 있으면 더 좋고요. 사실 이건 물리적인 기계 대부분과 다르지 않습니다. 기어가 들어가 있지 않은 차에서 가속 페달은 뭘 하죠? 게다가 기어 변속은 아예 별개의 입력 장치로 하잖아요.
(사실 사람들은 프로그래밍을 생각할 때 물리적인 기계를 충분히 들여다보지 않습니다. 모든 걸 기호 함수로 단순화해야 한다고 고집하죠. 입력은 적을수록 좋고 출력은 하나면 더 좋다는 식으로요. 인생이 그렇게 맞춰 주면 얼마나 좋겠어요.)
CD를 인자 없이 실행하면 현재 드라이브의 현재 디렉터리가 표시됩니다.CD E:는E:드라이브의 현재 디렉터리를 표시합니다.어느 쪽이든 상태는 바뀌지 않습니다.
그럼 거기에 더 얹으면 나아질 거라고 보세요?
그렇게 말한 적 없습니다. 이미 있는 것보다 눈에 안 보이는 상태를 더 관리해야 하는 데 따르는 어려움과 위험을 지적하는 건 충분히 타당한 비판이라고 생각해요. 다만 앞에서 나온 주장은 그게 아니었습니다. 적어도 제가 읽기에는요.
경로 이름은 눈에 안 보이는 상태가 있든 없든 언제나 정말 복잡합니다. 전체 경로를 펼치는 일은 그냥 운영체제 API에 맡기세요.
그다음이 경로 정규화입니다. 이게 특히 골치 아픈데, 두 경로가 정말 같은 파일시스템에 있는지 알아야 하는 특정 상황에서만 필요합니다. 마운트 지점이나 심볼릭 링크 때문에
C:\dir\file이C:\와 다른 드라이브에 있을 수 있거든요. 게다가 윈도에서는 경로 정규화가 일부 경우에 제대로 동작하지 않습니다. 파일시스템을 마운트할 때 볼륨을 마운트 관리자에 등록할 수 있는데, 등록하면 경로 정규화는 되지만 원치 않는 부작용("휴지통"과 "System Volume Information" 디렉터리 생성)도 따라옵니다. 등록하지 않으면 파일은 그대로 쓸 수 있지만 경로 정규화가 그 드라이브를 찾지 못합니다. 모든 드라이브 문자를 일일이 열거해서 찾아야 하고, 디렉터리 안에 마운트했다면 더 어렵습니다.저는 이 동작에 자주 의존합니다. MS-DOS 2.0 때부터 있던 거예요.
왜 끔찍하다는 거죠? 그냥 기본적이고 문서화도 잘 된 시스템 동작인데요.
bash를 비롯한 흔한 유닉스 계열 셸의 멋진 기능은 변수를 쓸 수 있다는 점입니다. 그래서 이렇게 할 수 있어요.
(한 디렉터리로 이동)
src=$PWD(다른 디렉터리로 이동)
dst=$PWD(원하는 곳으로 이동)
이제
ffmpeg -i "$src/scene1.mp4" "$dst/output-scene.mp4"라고 하면 됩니다.디렉터리와 파일 이름에 공백이나 특수 문자를 쓰지 않는다면 따옴표는 생략해도 됩니다.
게다가 시스템 전체의 파티션 방식에 얽매이지도 않으니 편하죠.
command.com에도 변수는 있어요. 문법이 영 별로라서 그렇지.
"subst"(https://en.wikipedia.org/wiki/SUBST)도 있습니다.
디렉터리를 드라이브인 것처럼 가장할 수 있어서, 결과적으로 한 드라이브에 현재 디렉터리를 여러 개 둘 수 있게 해 줍니다.
이 고객들은 레이먼드 천(Raymond Chen)이 1차 지원 담당으로 나서서 자기네 배치 파일을 디버깅해 주는 대가로 지원비를 얼마나 내는 걸까요?
최상위 엔지니어나 다른 VIP도 사람입니다. 그리고 그들이 얼마나 "낮은 곳"까지 내려오는지 알면 놀랄 때가 많아요.
대기업 CEO라고 하면 알현실에 앉아 하인을 통해서만, 그것도 아주 중요한 사안일 때만 만날 수 있는 사람, 수십억 달러짜리 계약 같은 것만 다루는 사람을 떠올리기 쉽습니다. 물론 그런 면도 있지만 그게 전부는 아니에요.
인턴 컴퓨터의 불량 이더넷 케이블을 교체해 준 사람이 알고 보니 그 CEO였다거나, AAA급 게임의 리드 개발자가 평범한 게이머에게 기본적인 기능을 참을성 있게 설명해 주고 있다거나 하는 일을 어쩌다 접할 수 있습니다. CTO가 아무 지원 전화나 받을 수도 있고요. 그러니 레이먼드 천이 .bat 스크립트의 "뻔한" 문제를 디버깅했다고 해서 저는 전혀 놀랍지 않습니다.
저도 지원 센터에 전화했는데 박봉에 시달리는 말단 직원을 예상했다가, 상담원이 정말 유능하고 참을성 있고 친절해서 알고 보니 그 제품을 통째로 만든 사람과 통화한 적이 있습니다. 그런 날은 하루가 즐거워지죠.
제가 어떤 최고위급 VIP라면 이런 순간을 소중히 여길 것 같습니다. 소박한 일, 진짜 사람과의 접촉, 직책에 딸린 막중한 책임에서 벗어난 시간이니까요. 직업적인 관점에서도 아래에서 무슨 일이 벌어지는지 감을 잡아 두는 건 중요합니다.
아니면 오히려, 이런 기본적인 기능조차 파악하지 못해서 천에게까지 올라오게 만든 초기 지원 단계가 얼마나 형편없었는지를 물어야 할지도 모릅니다.
아니면 그가 이미 그 고객사와 직접 프로젝트를 하던 중이었고, 이 건도 하던 업무의 일부였을 수도 있고요.
글에는 연도가 안 나와 있습니다. 초기 마이크로소프트 윈도는 문서화가 아주 부실했고 문서를 검색하기도 어려웠어요. 그래서 그걸 알려면 고참급 지원 담당이 필요했다 해도 놀랍지 않습니다.
게다가 실행 중인 것의 상태를 훨씬 자세히 보여 주는 Process Monitor 같은 도구도 없었죠.
2026년인 지금도 마찬가지예요.
네, 그래도 이제는 AI가 있잖아요. codex한테 McAfee 좀 지워 달라고 하세요.
msdn 문서를 제대로 이해하는 사람들이 부럽습니다. AI가 올해 그걸 대세 스타일로 만들기 수십 년 전부터 이미 지루하고 압도적인 문서였어요.
나은 부분도 있긴 한데, 세상에, 거기서 뭐 하나 찾으려면 거의 퀘스트예요.
유닉스 같은 환경이라면 프로그램이 보통 진단 정보를 터미널에 뿌려 주기 때문에 쉽게 알아냈을 거라고 생각합니다. 윈도에서는 아마 이전 경험으로 익혀야 하는 종류의 지식이었을 겁니다(실행되는 프로그램에 따라 달라지기도 하고요).
글에서 프로그램이 명령줄에 오류 메시지를 표시했다고 했습니다. 그게 터미널에 뿌려진 진단 정보잖아요.
레이먼드 천 같은 고참(적어도 훌륭한 사람들)은 풀 스택에 대한 이해를 최신으로 유지하려고 자기 수준보다 "아래"에 있거나 담당 범위 밖인 일을 어느 정도 해 가며 지금 자리까지 올라오는 경우가 많습니다.
그가 때때로 최하위 지원 큐를 훑어보면서 고객들이 어떤 문제를 겪는지, 어디가 불편한지 등을 파악하고 있다 해도 놀랍지 않습니다.
게다가 오래된 글이기도 합니다.
Patreon처럼 직원이 먼저 볼 수 있는 거죠.
그 격차가 얼마나 되는데요? 이 글은 지난주에 공개됐습니다.
링크된 글이 유익했고 제 짐작을 확인해 줬습니다. "클릭한 대상"이 꼭 실행 파일일 필요는 없고, 그 실행 파일이 실행 핸들러로 등록된 문서일 수도 있으며, 그 경우 현재 디렉터리는 그 문서가 있는 디렉터리가 됩니다.
링크나 셸 네임스페이스의 항목은 어떻게 처리되는지도 궁금하네요.
맞아요. 그런데 애플리케이션은 기본적으로 작업 디렉터리에서 DLL을 불러오고, 문서를 열면 작업 디렉터리가 설정되죠. 그러니 신뢰할 수 없는 폴더에 있는 문서는 절대 열지 않는 게 좋습니다.
애플리케이션은 기본적으로 작업 디렉터리에서 먼저 불러오지 않습니다.
하지만 기본적으로 작업 디렉터리에서도 불러오는 건 맞고[0], XP SP2 전까지는 기본 검색 순서에서 system32보다 앞에 두었습니다[1].
[0] https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order
[1] https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-security