tar 몇가지. files-from(Include), exclude-from(Exclude)

이 글에선 tar 에 관한 몇가지를 정리하고자 한다.

먼저, 인터넷에서 찾은 많은 tar 예문은, 아래와 같이 크게 두가지 경우로 나눌 수 있다.

tar xvf ....
tar -xvf ....

즉, 줄표가 있고 없고 차이인데, 이게 도대체 어떻게 다른 걸까??
(간혹, –create 등으로 좀 더 길게 쓰는 경우도 있다.)

답은 늘, 파랑새가 쥐고 있다.
man page 첫 문단에 이렇게 나와있었다.

NAME
       tar - an archiving utility

SYNOPSIS
   Traditional usage
       tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...]

   UNIX-style usage
       tar -A [OPTIONS] ARCHIVE ARCHIVE

       tar -c [-f ARCHIVE] [OPTIONS] [FILE...]

       tar -d [-f ARCHIVE] [OPTIONS] [FILE...]

       tar -t [-f ARCHIVE] [OPTIONS] [MEMBER...]

       tar -r [-f ARCHIVE] [OPTIONS] [FILE...]

       tar -u [-f ARCHIVE] [OPTIONS] [FILE...]

       tar -x [-f ARCHIVE] [OPTIONS] [MEMBER...]

   GNU-style usage
       tar {--catenate|--concatenate} [OPTIONS] ARCHIVE ARCHIVE

       tar --create [--file ARCHIVE] [OPTIONS] [FILE...]

       tar {--diff|--compare} [--file ARCHIVE] [OPTIONS] [FILE...]

       tar --delete [--file ARCHIVE] [OPTIONS] [MEMBER...]

       tar --append [-f ARCHIVE] [OPTIONS] [FILE...]

       tar --list [-f ARCHIVE] [OPTIONS] [MEMBER...]

       tar --test-label [--file ARCHIVE] [OPTIONS] [LABEL...]

       tar --update [--file ARCHIVE] [OPTIONS] [FILE...]

       tar --update [-f ARCHIVE] [OPTIONS] [FILE...]

       tar {--extract|--get} [-f ARCHIVE] [OPTIONS] [MEMBER...]

그냥, 맘에 맞는대로 아무렇게나 써도 된다. 다만, 헷갈릴 수 있으므로 어느 한 가지를 택해 사용하는 편이 좋겠다.


밑밥은 여기까지. 이 글에서 정리하고자 하는 바는, ‘파일목록’을 외부 파일로 만든 뒤, 그 목록에 있는 파일들만 포함시키거나, 또는 포함시키지 않는 방법이다.

먼저, 몇몇 파일/디렉토리만 tar 에 포함시키려면? 파일을 하나씩 끝에 써붙여도 된다. 그러나, 그 파일이 여기 저기, 서너 개만 넘어가도 명령어 내에 직접 붙이기란 힘들다.

이럴 때, 파일목록을 따로 만들어서 그 파일을 읽어오는 방식을 취할 수 있다.

tar --create \
	--file=~/my-backup.tar \
	--files-from=~/include-dir

위 명령은, ~/include-dir 이라는 파일에서, 복사할 파일목록을 가져오라는 뜻이다. 물론, 이 파일명은 원하는대로 주면 된다.
include-dir 파일의 형식은 이렇다.

/home/myuserid/.anacron
/home/myuserid/.config
/home/myuserid/.gnupg
/home/myuserid/.keychain
/home/myuserid/.local
/home/myuserid/.oh-my-zsh
/home/myuserid/.ssh
/home/myuserid/.wine
/home/myuserid/.bashrc
/home/myuserid/.profile
/home/myuserid/.selected_editor
/home/myuserid/.viminfo
/home/myuserid/.vimrc
/home/myuserid/.Xauthority
/home/myuserid/.xinputrc
/home/myuserid/.zprofile
/home/myuserid/.zshrc

이런 식으로, 전체 경로를 적어주면 된다. $HOME 등의 변수는 인식하지 못하므로 주의가 필요하다.
명령어에 직접 입력할 때는 변수를 사용할 수 있지만, ‘목록’에 넣을 때는 순수한 파일명(경로포함)만 인정된다.

그런데.. 이렇게 하고 보니, 하위 디렉토리 중 불필요한 파일(디렉토리)이 있음을 발견했다. 예를 들어, ~/.local/share/baloo 디렉토리는 굳이 보관을 할 필요도 없고, 내부에 있는 파일 크기도 무척 크다.

이런 식으로 제외하고 싶은 파일이 있다면, –exclude-from 을 쓰면 된다.

tar --create \
	--file=~/my-backup.tar \
	--exclude-from=~/exclude-dir \
	--files-from=~/include-dir

–exclude-from 으로 읽어들일 파일 형식도 –files-from 때와 똑같다.

그런데.. 살짝 헷갈리는 게 있고, 결과도 좀 알쏭달쏭한데.. 위는 –exclude-from 을 먼저 쓰고 –files-from 을 나중에 썼다. 그런데, 이를 뒤바꿔도 결과가 같을까?

예를 들어, 이런 경우를 생각해 볼 수 있다.
/home/myuser/.local 이 ‘포함(–files-from)’하되, ‘/home/myuser/.local/baloo’ 은 제외(–exclude-from)하고 싶다!

include-dir 파일에 /home/myuser/.local 을 넣고, exclude-dir 파일에 /home/myuser/.local/baloo 를 넣으면 될 듯 한데..

결과는 이렇게 나왔다.
용량이 큰 파일은 files-from 이 앞에 있었을 때 결과고, 작은 파일은 exclude-from 이 앞에 있었을 때 결과, 즉 원했던 결과다.

-rw-rw-r-- 1 myuserid myuserid 1.8G 2020-05-23 12:16 test-excl-inc-2.tar
-rw-rw-r-- 1 myuserid myuserid 4.5G 2020-05-23 12:15 test-inc-excl-1.tar

files-from 이 앞에 있으면, exclude-from 을 고려하기 전에 이미 복사가 이뤄진다. 따라서 exclude-from 에서 명시된 제외파일들이 그냥 들어가 버렸다.

따라서, files-from 과 exclude-from 을 동시에 사용하고자 할 때, 특히 include/exclude 간 디렉토리가 연관되어 있을 경우, exclude-from 을 먼저 써주는 편이 맞다고 여겨진다. (여겨지는 정도가 아니고, 이렇게 해야만 한다.)

위에도 있지만, 다시 한번 적어본다.

tar --create \
	--file=~/my-backup.tar \
	--exclude-from=~/exclude-dir \
	--files-from=~/include-dir

이렇게 exclude 를 앞에 쓰는게, 적어도 내가 시험해본 바로는, 내가 원하는 결과를 얻을 수 있는 방식이었다.

Gnu 공식 문서(Reading Names from a File, Excluding Some Files)를 참고했는데, 이런 내용은 찾질 못했다.


마지막. –files-from 에는, 파일명만 아니라 추가 선택사항도 들어갈 수 있다고 한다.

예를 들어, 다음과 같이 -C 도 사용할 수 있다.

$ cat list
-C/etc
passwd
hosts
-C/lib
libc.a
$ tar -c -f foo.tar --files-from list

passwd 는 /etc/passwd 가 되고, libc.a 는 /lib/libc.a 가 된다. 기타 여러 옵션도 쓸 수 있다고 한다.

Tags:,

안녕하세요. 글 남겨주셔서 고맙습니다.