2008년 9월 12일 금요일

[Tip] Linux/Unix에서 압축파일 다루기


물론 zip이나 rar 또는 7zip과 같은 압축파일형식은 Platform에 구애받지 않고 사용될 수 있고 실재로 많이 사용되고 있기는 하지만, Linux/Unix에서 가장 자주 만나게 되는 압축파일은 filename.tar.gz 와 filename.tar.bz2와 같은 형식이다.
(최근의 Data Compression Software들은 다양한 format을 지원하고 있기 때문에 tar.gz나 tar.bz2 등도 적절한 Windows Utility를 사용하면 MS Windows에서 사용하는 데 큰 어려움은 없다.)
Kernel Source라든지 Application들의 Source Package들도 주로 이 두가지 형식으로 배포된다.
이러한 압축파일들은 tar 명령과 gzip, bzip2와 같은 Utility들을 이용하여 만들어질 수 있다.

===| TAR |=======================
TAR는 UNIX의 standard archive utility로서 원래 Tape ARchiving program에서 유래하였다.
지정된 여러 개의 file들을 archive라고 부르는 하나의 file로 만들거나, 하나의 archive에 모아져 있는 여러 개의 file을 원래의 형태대로 추출해내는 UNIX SHELL command이다.
tar archive에는 ".tar"라는 확장자가 붙는다. tar archive 내에 들어있는 file들은 압축되는 것이 아니라, 단지 하나로 모아지는 것뿐이다. 흔히 tar로 묶어진 archive를 "tarball"이라 부르기도 한다. 이러한 tar archive를 gzip이나 bzip2로 다시 압축한 것이 archive-name.tar.gz와 archive-name.tar.bz2이다.

$ tar cvf backup.tar /home/jvm
이 명령은 /home/jvm 안의 모든 file을 backup.tar의 이름으로 묶는다. 첫 번째 argument인 "cvf" 는 tar의 option으로서, "c"는 새로운 file을 생성(create)하며, "v"는 명령이 수행되는 세부 process를 화면에 출력될 것을 지정한다(verbose). "f"는 생성될 file의 이름을 다음에 나오는 argument인 backup.tar로 지정한다(file). 마지막 argument는 압축이 될 file이나 directory이다.

# tar xvf backup.tar
current directory의 backup.tar를 푼다(extract). tar로 묶인 것을 풀 때 기존의 file들을 덮어쓰게 되므로 주의를 요한다. backup.tar가 directory를 포함한다면, 자동적으로 directory가 생성되고 file이 속하게 된다. 
  
===| compress |=======================
근래에는 잘 사용하지 않는 compress의 경우 가장 먼저 나와서 가장 오랫동안 사용되었으나, algorithm에 대한 Software License 문제와 gzip의 효율이 compress 보다 좋다는 점, 그리고 gzip으로도 compress를 이용해 압축된 file을 다룰 수 있다는 등의 이유로 gzip(GNU Zip)으로 대치되었다.

compress로 압축된 file의 끝에는 확장자 .Z가 붙는다. 예를 들면,
$ compress backup.tar 라는 명령으로 backup.tar를 compress를 사용해 압축하면 backup.tar.Z이 만들어진다.
압축을 해제할 때에는 다음과 같이 uncompress를 이용한다.
$ uncompress backup.tar.Z 해주면 backup.tar가 풀려나온다.

===| GZip |=======================
GNU Zip(gzip)은 compress 명령보다 더 나은 Data Compression기능을 갖고 있으며 주로 tar로 묶여진 archive를 다시 압축할 때 사용하게 된다.
압축파일에는 ".gz"라는 확장자가 붙는다.

$ gzip -9 backup.tar 와 같이 명령을 주면 최상의 압축률(-9)로 backup.tar를 압축한 backup.tar.gz가 만들어진다.
이것을 Pipe와 Redirection을 사용하여
$ tar cvf - /home/jvm | gzip -9c > backup.tar.gz 와 같이 해주어도 된다.
(먼저 tar file을 tar의 표준출력(-)으로 보내고, 이것은 gzip과 pipe되어 들어오는 tar file을 압축하여 그 결과를 backup.tar.gz로 redirect시킴으로써 file로 저장된다. gzip의 -c option은 출력을 redirect하기 위해 표준출력으로 보낸다.)

압축을 해제하기 위한 명령은 gunzip이다. 이것은 gzip -d와 동일하다.
$ gunzip backup.tar.gz 명령을 통해 backup.tar가 풀려나오고,
$ tar xvf backup.tar 해주면 archive가 풀려진다.
이 두 명령을 한 번에 하려면
$ gunzip -c backup.tar.gz | tar xvf - 와 같이 하면된다.
(gunzip은 bacup.tar.gz의 압축을 해제하고, 그 결과를 표준출력으로서 tar에 보낸다. -는 tar의 표준출력.)
이제 흔히 볼 수는 없지만 확장자가 .taz이거나 .tgz인 archive들을 어디선가 만날 수 있다.
Linux/Unix에서는 file을 하나의 archive로 인식하기 위하여 어떤 특정한 확장자를 꼭 붙여줄 필요가 없다. 단지 알아보기 편하도록 tar로 묶으면 확장자 .tar를 붙이고, 이것을 압축하면 .tar.Z나 .tar.gz와 같은 확장자가 붙게 된 것이다.
그렇지만 MS-Dos System에서는 이러한 이중확장자를 사용할 수 없었기 때문에 .tar.Z와 동일한 .taz확장자와 .tar.gz와 동일한 .tgz가 사용되었다. 이러한 압축을 푸는 방식은 물론 .tar.Z와 .tar.gz와 동일하다.


===| bzip2 |=======================
bzip2는 Lossless Data Compression Algorithm으로
Burrows-Wheeler Transform(Block-Sorting Compression)을 써서 자주 반복되는 Character String을 같은 Character String로 변환한 다음 MTF(move-to-front) Transform, Huffman Coding을 차례대로 적용하는 구조이다. gzip이나 zip에 비해 압축률이 좋지만 느리다.(13MByte 정도 크기의 text file을 압축하면 354kByte가 되었다고 하니 놀랄만한 압축률이다.)
bzip2 자체적으로는 다중파일을 다루거나 분할압축, 암호화 등의 기능이 없다. 그러한 기능은 tar와 같은 다른 Utility가 대신하게 된다. 특징이나 사용할 수 있는 option은 gzip과 거의 같다.
압축파일에는 ".bz2"라는 확장자가 붙는다.

$ bzip2 backup.tar 와 같이 명령을 주면 backup.tar를 압축한 backup.tar.bz2가 만들어진다.
이것을 Pipe와 Redirection을 사용하여
$ tar cvf - /home/jvm | bzip2 > backup.tar.gz 와 같이 해주어도 된다.

bzip2는 압축만 할 수 있고 archive 기능은 가지고 있지 않다.
또한 위에서 다중파일을 다루지 못한다고 하였는데 여러 file들을 각각 동시에 압축하는 것은 가능하다.
예를 들어 file1, file2, file3 가 있는 directory에서
$ bzip2 * 와 같이 명령을 주면 file1.bz2, file2.bz2, file3.bz2 가 생성된다.
$ bunzip2 * 해주면 file1, file2, file3가 동시에 풀려져 나온다.

압축을 해제하기 위한 명령은 bunzip2이다. 이것은 bzip2 -d와 동일하다.
$ bunzip2 backup.tar.gz 명령을 통해 backup.tar가 풀려나오고,
$ tar xvf backup.tar 해주면 archive가 풀려진다.
이 두 명령을 한 번에 하려면
$ bunzip2 -c backup.tar.gz | tar xvf - 와 같이 하면된다.

[Tip]
BSD와 GNU Version tar는 compress와 gzip압축을 다룰 수 있는 option(Z / z)와
bzip2압축을 다룰 수 있는 option(j)가 patch되어 있다.
따라서 pipe를 사용하지 않고 한 번의 명령으로 압축이나 해제를 할 수 있다.

$ tar czvf  archive-name.tar.gz * 라고 하면 하위 디렉토리를 포함한 모든 파일을 tar로 묶어서(.file은 제외) gzip으로 압축하라는 의미이다.
(Z option에 archive-name.tar.gz 대신에 archive-name.tar.Z를 사용하면 compress로 압축.)
$ tar xzvf archive-name.tar.gz와 같이 z option을 사용하여 tar.gz을 한 번에 압축해제 가능.
(Z option에 archive-name.tar.gz 대신에 archive-name.tar.Z를 입력하면 compress 압축해제.)
하위 디렉토리를 포함한 모든 파일을 tar로 묶어서(.file은 제외) bzip2로 압축하려면
$ tar cjvf  archive-name.tar.bz2 *
tar.bz2를 한 번에 압축해제 시키려면
$ tar xjvf archive-name.tar.bz2
결론적으로 여러 Data Compression Software들이 있지만 tar 하나만 잘 활용하면 .tar, .tar.Z, .taz, .tar.gz, .tgz, .tar.bz2 와 같은 확장자를 가진 모든 압축파일을 문제없이 사용할 수 있다.

<추가>
tar의 info page를 찾아보다가 그동안 정확히 알고 있지 못하던 내용을 새로이 보게되어 추가한다.
tar에서 option을 주는 방법은 Long option / Short option / Old style option 세가지가 있다.
--verbose 이렇게 사용하는 것은 Long option,
-v 이렇게 쓰는 것은 Short option이고 Old style option은 Short option과 마찬가지로 Single letter이다.
그러나 단독으로 사용할 수는 없고 공백없이 option letter들을 붙여쓴다.
위에서 tar에 대한 예로서 사용한 명령들은 다 Old style option을 사용하였다.
tar --create --file=archive.tar file1
tar -cf archive.tar file1
tar cf archive.tar file1
이 세 명령은 모두 동일하다. 그렇지만 조심해야할 경우가 있다.
tar -cfz archive.tar.gz file1
tar cfz archive.tar.gz file1
이 두 명령은 전혀 다르다. Old style option의 경우 f option에 대한 value로서 archive.tar.gz를 사용하고,
gzip압축을 위한 option으로서 z를 인식하게 된다. 이와 같은 기대를 하고 tar -cfz archive.tar.gz file1
사용하면 전혀 의외의 결과를 얻게된다. 왜냐하면 이 경우 z가 f option에 대한 value로 받아들여져 버리기
때문이다. 하지만 다음과 같이 사용함으로써 이 문제를 피할 수 있다.
tar -czf archive.tar.gz file1
tar -cf archive.tar.gz -z file1
tar cf archive.tar.gz -z file1
Old style option은 구버전의 tar와의 호환성을 위해 유지되고 있다.
Long option의 경우 단어 자체를 사용하므로 직관적이나 길어서 불편하다.
개인적으로는 Old style option이 편하긴 하지만 아무래도 Short option 형태를 사용하는 것이 나을 것도 같다.
다만 f option의 경우처럼 value가 바로 따라오는 syntax를 가진 경우를 조심해야한다.

댓글 6개:

  1. 제 경우 아무생각없이 tar zxvf 를 사용했는데 tar에 관해, z옵션에 관해 잘 이해하고 갑니다.

    답글삭제
  2. 와.. 정말 정리가 잘 되어있네요. 잘 보겠습니다! ^^

    답글삭제
  3. 사실 자주 쓰는 명령만 외워서 쓰다가 전반적으로 한 번 정리를 해야할 필요성이 있다고 느껴 정리를 시작했는데 전체적으로 핵심만 뽑아 정리한다는 것이 생각보다 간단치가 않아서 시작한 날부터 완료한 날까지 상당히 많은 시간이 소요되었습니다. 나름대로 고생해서 정리한 만큼 잘 보셨다고들 말씀해주시니 보람을 느낍니다.

    답글삭제
  4. 잘 보고 갑니다. 정말 좋은 내용!

    답글삭제
  5. 자체 서버를 운영할 때에는 매일 씨름하던 것이 유닉스였는데,,, 요즘은 유닉스는 거의 처다도 보지 않고 사는군요.

    답글삭제
  6. @도아 - 2008/09/28 16:57
    저도 사실 윈도우스보다는 유닉스를 훨씬 좋아하지만 이제는 자주 접하질 않으니 아는 것이 늘기는 커녕 얼마 안되는 기존에 공부한 것도 점점 잊혀져만 갑니다.

    답글삭제