2026년 6월 16일 | 개발 깨알 상식_Tips
압축 파일은 열기 전까지 내부 경로가 보이지 않아서, 작은 테스트 자료도 생각보다 쉽게 현재 디렉터리를 어지럽힌다. 특히 외부에서 받은 .tar.gz나 .zip을 습관처럼 바로 풀면 파일이 어디에 생길지, 기존 파일을 덮을지, 상위 디렉터리를 건드릴 여지가 있는지 확인할 틈이 없다. 나는 압축 해제를 설치나 배포만큼 위험한 작업으로 보지는 않지만, 실제 파일을 만들기 전에 목록을 먼저 보는 단계는 거의 항상 넣는 편이다.
목록이 먼저여야 하는 이유
압축 해제에서 가장 싫은 상황은 명령이 실패하는 것이 아니라, 성공한 뒤에야 “이 파일들이 여기 풀리면 안 됐는데”를 깨닫는 쪽이다. 실패는 눈에 띄지만, 엉뚱한 위치에 생긴 파일이나 조용한 덮어쓰기는 나중에 다른 오류로 돌아온다. 그래서 나는 실제 추출 명령보다 먼저 아래처럼 목록 명령을 실행한다.
tar -tf dataset.tar.gz | sed -n '1,40p'
unzip -l result.zip | sed -n '1,40p'
tar -tf는 tar 아카이브의 멤버 이름을 먼저 보여 주고, unzip -l은 ZIP 안의 파일명과 크기, 날짜를 보여 준다. 여기서 핵심은 전체를 다 읽는 것이 아니다. 처음 몇 줄만 봐도 최상위 디렉터리가 하나로 묶였는지, 갑자기 루트 경로처럼 보이는 항목이 있는지, 파일 수가 예상보다 많은지 감이 온다. 큰 파일을 풀기 전에 10초 정도 쓰는 셈인데, 잘못 풀었을 때 정리하는 시간과 비교하면 꽤 싸다.
내가 먼저 표시해 두는 신호
목록을 볼 때는 예쁜 파일명보다 위험한 모양을 먼저 찾는다. ../가 들어간 경로, /home/...처럼 절대경로처럼 보이는 항목, 최상위 폴더 없이 파일이 바로 여러 개 흩어지는 구조, 같은 이름의 파일이 반복되는 구조가 먼저 눈에 들어와야 한다. 심볼릭 링크가 섞인 tar도 조심한다. 링크 자체가 나쁘다는 뜻은 아니지만, 추출 후 실제 경로가 내가 생각한 폴더 안에 머무는지 한 번 더 봐야 한다.
GNU tar나 unzip에는 나름의 안전장치가 있다. 예를 들어 GNU tar는 아카이브를 만들거나 다룰 때 앞쪽의 /를 제거하는 동작을 보여 주고, unzip도 보안상 부모 디렉터리 성분을 다루는 방식을 갖고 있다. 그래도 나는 이걸 믿고 바로 푸는 쪽보다, 도구의 방어와 내 사전 확인을 서로 다른 층으로 둔다. 안전장치가 있다는 사실은 고맙지만, 내가 풀려는 파일의 구조를 모르는 상태를 없애 주지는 않는다. 그래서 목록 확인은 방어 기능의 대체물이 아니라, 사람이 작업 범위를 이해하는 별도 단계로 둔다.
무결성 검사는 구조 검사와 다르다
unzip -t는 ZIP 파일을 메모리로 테스트해서 CRC 같은 무결성 문제를 확인하는 데 유용하다. 다운로드가 깨졌는지, 압축 파일 자체가 읽히는지 확인할 때는 이 옵션이 좋다. 다만 통과했다고 해서 “안전하게 풀어도 된다”는 뜻은 아니다. 무결성 검사는 파일이 손상됐는지를 보고, 구조 검사는 파일이 어디에 풀릴지를 본다. 둘은 서로 다른 질문이다.
tar 쪽에서도 압축 스트림이 깨졌는지 확인하는 과정과 멤버 경로를 보는 과정은 분리해서 생각하는 편이 낫다. 나는 외부 자료를 받으면 먼저 목록을 보고, 필요하면 압축 자체의 테스트를 한 번 더 한 뒤, 마지막에 추출 위치를 정한다. 순서가 조금 길어 보이지만 자동화에 넣으면 결국 세 줄이다. 중요한 건 검사 명령 하나로 모든 위험을 해결했다고 착각하지 않는 것이다.
추출 위치를 비워 두면 판단이 단순해진다
목록이 괜찮아 보여도 바로 현재 작업 폴더에 풀지는 않는다. 가능하면 비어 있는 임시 폴더를 만들고, 그 안으로만 추출한다.
mkdir -p scratch-archive
tar -xf dataset.tar.gz -C scratch-archive
unzip -n result.zip -d scratch-archive
tar -C와 unzip -d는 추출 위치를 명시한다. unzip -n은 기존 파일을 덮어쓰지 않도록 해 주기 때문에, 이미 파일이 있는 폴더에서 실수로 실행했을 때도 피해를 줄인다. 반대로 unzip -o처럼 묻지 않고 덮어쓰는 옵션은 자동화에서는 편하지만, 내가 의도한 덮어쓰기인지 설명할 수 있을 때만 쓴다. 압축 파일은 “읽기”가 아니라 파일 생성 작업이므로, 작업 반경을 먼저 좁혀 놓는 편이 마음이 편하다.
권한과 링크도 같이 보기
파일명만으로 충분하지 않을 때는 verbose 목록을 본다. tar에서는 tar -tvf를 쓰면 파일 종류, 권한, 소유자, 크기 같은 정보가 함께 나온다. 여기서 맨 앞 문자가 l로 시작하면 심볼릭 링크이고, 실행 권한이 지나치게 넓거나 소유자 정보가 낯설게 보이면 한 번 멈춘다. ZIP은 형식상 tar만큼 Unix 권한을 또렷하게 보여 주지 못하는 경우가 있지만, unzip -l의 크기와 경로만 봐도 “이 압축 파일이 단순 문서 묶음인지, 실행 파일과 숨은 폴더가 섞인 배포물인지” 정도는 가를 수 있다.
나는 특히 모델 가중치, 로그 번들, 데이터 샘플처럼 출처가 여러 번 옮겨 다닌 파일에서 이 단계를 자주 쓴다. 처음 만든 사람이 악의적이었다기보다, 중간에 누군가의 홈 디렉터리 구조나 빌드 산출물이 그대로 들어갔을 가능성이 있기 때문이다. 압축 파일은 만든 사람의 작업 폴더 냄새를 생각보다 많이 품고 있다. 그래서 목록을 보는 일은 보안 검사라기보다, 상대방의 폴더 구조를 내 작업 폴더로 들여오기 전에 하는 인수검사에 가깝다.
자동화에 넣을 때의 기준
스크립트에 압축 해제를 넣을 때는 목록 출력을 로그로 남기는 쪽이 좋다. 나중에 “왜 이 파일이 생겼지”를 따질 때 추출 결과만 보면 원래 압축 파일 안에 있던 구조인지, 중간 처리에서 생긴 구조인지 헷갈린다. 목록 로그가 있으면 압축 파일의 원래 모양과 추출 후 폴더를 비교할 수 있다. 작은 차이지만, 배치 작업이 실패했을 때 원인 범위를 줄이는 데 도움이 된다. 특히 같은 이름의 파일이 여러 번 들어 있는 아카이브는 추출 순서에 따라 마지막 파일만 남을 수 있으니, 목록 단계에서 중복 이름을 먼저 확인해 두면 나중에 훨씬 덜 헷갈린다.
내 기준은 단순하다. 외부에서 받은 압축 파일, CI에서 내려받은 빌드 산출물, 실험 데이터처럼 다시 만들기 어려운 파일은 바로 풀지 않는다. 먼저 목록을 보고, 위험 경로를 표시하고, 빈 디렉터리에 풀고, 필요한 파일만 원래 위치로 옮긴다. 이 네 단계를 거치면 압축 해제가 대단한 보안 절차가 되지는 않아도, 어디에 무엇을 만들었는지 설명 가능한 작업은 된다. 개발 팁이라고 하기엔 작아 보이지만, 이런 작은 사전 확인이 작업 폴더를 깨끗하게 지키는 데 꽤 효과가 있었다.
'[개발 깨알 상식_Tips]' 카테고리의 다른 글
| JSONL 빈 줄과 BOM이 만든 배치 파싱 오류 (0) | 2026.06.18 |
|---|---|
| CSV 식별자 컬럼의 숫자 추론 오류 (0) | 2026.06.17 |
| 설치 전에 의존성 계획 먼저 남기기 (0) | 2026.06.15 |
| 실행 전에 문법 오류 먼저 걸러내기 (0) | 2026.06.13 |
| JSON 검사를 실패 신호로 바로 세우기 (0) | 2026.06.03 |