Devin.KR
로그인

리눅스 tar 명령어 사용법 - 압축과 해제 옵션 정리, 실전 예제

개발자 조회 1

이 명령어를 언제 쓰는가

배포 아티팩트를 만들 때, 로그 디렉터리를 통째로 백업할 때, 파일 수만 개짜리 디렉터리를 다른 서버로 옮길 때 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 / -Jgzip / 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.gzdata/묶을 대상으로 읽는다. 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-targtar)를 쓴다.

함께 보면 좋은 명령어

  • rsync — 반복 동기화라면 매번 새로 묶는 tar 보다 훨씬 효율적이다.
  • find — 조건에 맞는 파일만 골라 -T - 로 tar 에 넘길 때 함께 쓴다.
  • gzip — 압축률과 속도를 조절하거나(-1~-9), 이미 만든 tar 를 따로 압축할 때 쓴다.