리눅스 tar 명령어 사용법 - 압축과 해제 옵션 정리, 실전 예제
이 명령어를 언제 쓰는가
배포 아티팩트를 만들 때, 로그 디렉터리를 통째로 백업할 때, 파일 수만 개짜리 디렉터리를 다른 서버로 옮길 때 tar를 쓴다. 원래 목적은 여러 파일을 하나로 묶는 것이고, 압축은 -z·-j 같은 옵션으로 덧붙는 기능이다.
파일이 많을수록 값어치가 커진다. 작은 파일 5만 개를 scp 로 보내면 파일마다 왕복이 생겨 한참 걸리지만, tar 로 묶어 한 덩어리로 보내면 몇 배 빠르다. 권한, 소유자, 심볼릭 링크, 수정 시각이 그대로 보존된다는 점도 백업 도구로 쓰이는 이유다.
기본 형식
tar [동작] [옵션] -f 아카이브파일 [대상...]
- 동작 —
-c(만들기),-x(풀기),-t(목록 보기) 중 정확히 하나를 고른다. - -f 아카이브파일 — 다룰 파일명.
-f바로 뒤에 파일명이 와야 한다. - 대상 — 묶을 파일·디렉터리. 풀 때는 생략하면 전부, 적으면 그것만 푼다.
자주 쓰는 옵션
| 옵션 | 의미 | 예시 |
|---|---|---|
-c | 새 아카이브를 만든다 | tar -czf logs.tar.gz logs/ |
-x | 아카이브를 푼다 | tar -xzf logs.tar.gz |
-t | 내용 목록만 본다(풀지 않는다) | tar -tzf logs.tar.gz |
-f | 대상 아카이브 파일 지정 | -f backup.tar.gz |
-z / -j / -J | gzip / bzip2 / xz 압축 | tar -cJf src.tar.xz src/ |
-v | 처리 중인 파일을 출력 | tar -czvf logs.tar.gz logs/ |
-C 디렉터리 | 해당 디렉터리로 이동한 뒤 작업 | tar -xzf app.tar.gz -C /opt/app |
-p | 권한을 그대로 복원(root 로 풀 때는 기본) | tar -xpzf etc.tar.gz |
--exclude='패턴' | 제외할 경로. 대상보다 앞에 쓴다 | --exclude='*.log' |
--strip-components=N | 풀 때 상위 디렉터리 N 단계를 벗긴다 | --strip-components=1 |
실전 예제
1. 로그를 날짜 붙여 백업한다. 압축본을 만들고 원본을 지우는 야간 배치의 기본형이다.
cd /var/log
tar -czf /backup/nginx-$(date +%F).tar.gz nginx/
cd 로 먼저 이동하는 이유는 절대경로를 그대로 묶지 않기 위해서다. tar -czf x.tar.gz /var/log/nginx 처럼 절대경로를 주면 다음 경고가 뜬다.
tar: Removing leading `/' from member names
2. 풀기 전에 내용을 먼저 확인한다. 남이 준 아카이브는 예외 없이 이 단계를 거친다.
tar -tzf app-1.4.0.tar.gz | head
app-1.4.0/
app-1.4.0/bin/
app-1.4.0/bin/start.sh
app-1.4.0/lib/app.jar
app-1.4.0/conf/application.yml
최상위가 app-1.4.0/ 하나로 묶여 있으면 안전하다. 반대로 bin/, conf/ 가 바로 나오면 현재 디렉터리에 그대로 쏟아진다.
3. 원하는 위치에 상위 디렉터리를 벗기고 푼다. 버전명 디렉터리가 한 겹 끼어 있는 배포 파일에 자주 쓴다.
sudo mkdir -p /opt/app
sudo tar -xzf app-1.4.0.tar.gz -C /opt/app --strip-components=1
4. 임시 파일 없이 원격 서버로 통째로 옮긴다. 디스크에 여유가 없거나 파일 개수가 많을 때 쓰는 형태다. 중간 파일을 만들지 않고 파이프로 바로 넘긴다.
tar -czf - -C /var/www app | ssh deploy@10.0.1.30 'tar -xzf - -C /srv'
-f - 는 표준입출력을 쓰라는 뜻이다. 앞쪽 - 는 표준출력으로 내보내고, 뒤쪽은 표준입력에서 읽는다.
5. 불필요한 것을 빼고 소스만 묶는다. 제외 옵션은 반드시 대상 경로 앞에 둔다.
tar -czf src-$(date +%F).tar.gz \
--exclude='.git' --exclude='node_modules' --exclude='*.log' \
./myapp
6. 아카이브에서 파일 하나만 꺼낸다. 전부 풀 필요 없이 설정 파일 하나만 확인할 때 쓴다.
tar -xzOf app-1.4.0.tar.gz app-1.4.0/conf/application.yml | head -20
-O 는 파일로 쓰지 않고 표준출력으로 보내라는 뜻이다. 옵션은 아카이브 이름보다 앞에 둔다. GNU tar 는 뒤에 붙여도 알아서 처리하지만 macOS 의 bsdtar 는 -O 를 꺼낼 파일 이름으로 읽어 Not found in archive 를 내면서 파일은 현재 디렉터리에 풀어버린다.
함정과 주의점
-f 뒤에는 반드시 아카이브 파일명이 와야 한다. 묶음 옵션의 순서를 한 글자 바꾸면 전혀 다른 명령이 된다.
tar -cfz backup.tar.gz data/ # 잘못
tar -czf backup.tar.gz data/ # 올바름
앞의 명령은 -f 의 인자가 z 로 잡혀 z 라는 이름의 비압축 tar 를 만들고, backup.tar.gz 와 data/ 를 묶을 대상으로 읽는다. gzip 압축도 걸리지 않는다. 기존 backup.tar.gz 가 덮어써지지는 않지만 정작 원하던 압축본은 생기지 않고, tar 는 오류 없이 0 으로 끝나기 때문에 야간 배치에 이렇게 들어가 있으면 몇 달치 백업이 비어 있다는 사실을 복구할 때 처음 알게 된다. 옵션은 czf, xzf, tzf 세 덩어리로 통째로 외우는 것이 안전하다.
확인 없이 푼 아카이브가 현재 디렉터리를 오염시킨다. 최상위 디렉터리 없이 파일이 흩어져 있는 아카이브를 홈이나 /etc 에서 풀면 기존 파일을 덮어쓴다. 되돌릴 방법이 없다. 항상 -t 로 먼저 보거나, 빈 디렉터리를 만들고 -C 로 그 안에 푼다.
절대경로로 묶은 아카이브는 복원 위치를 고를 수 없다. GNU tar 는 기본적으로 앞의 / 를 떼어 경고를 내지만, -P 옵션으로 만든 아카이브는 절대경로가 그대로 들어간다. 그런 파일을 root 로 풀면 운영 중인 /etc 를 덮어쓴다.
macOS 의 tar 는 GNU tar 가 아니다. macOS 는 bsdtar 를 쓰기 때문에 --exclude 의 패턴 해석, 옵션 순서 허용 범위, 확장 속성 처리가 다르다. 또 맥에서 만든 아카이브에는 ._ 로 시작하는 리소스 파일이 섞여 들어가 리눅스 서버에서 지저분해진다. COPYFILE_DISABLE=1 tar -czf ... 로 막거나, GNU tar(brew install gnu-tar 의 gtar)를 쓴다.
함께 보면 좋은 명령어
rsync— 반복 동기화라면 매번 새로 묶는 tar 보다 훨씬 효율적이다.find— 조건에 맞는 파일만 골라-T -로 tar 에 넘길 때 함께 쓴다.gzip— 압축률과 속도를 조절하거나(-1~-9), 이미 만든 tar 를 따로 압축할 때 쓴다.