アーカイブを任意のディレクトリに展開・作成したい

tarコマンドは、実行時のカレントディレクトリを基準にアーカイブを展開・作成する。カレントディレクトリ以外の場所に展開したい場合、cdで移動してからtarを実行し、終わったら元のディレクトリへ戻るという手順が必要になる。tarコマンドの-Cオプションを使うと、指定したディレクトリへ移動した状態でアーカイブを展開・作成でき、cdによる移動が不要になる。

-C オプションの基本

-C DIRECTORYを指定すると、アーカイブを展開・作成する前に指定したディレクトリへ移動する。

$ tar -xzf archive.tar.gz -C dir/

-Cで指定するディレクトリは事前に存在している必要があり、存在しない場合はエラーになる。

具体例

以下のような構造のmyproject.tar.gzがあるとする。

myproject/
├── src/
│   └── main.go
├── config/
│   └── app.yaml
└── README.md

-Cを指定せずに展開すると、カレントディレクトリに展開される。

$ tar -xzf myproject.tar.gz
$ find myproject -type f
myproject/README.md
myproject/src/main.go
myproject/config/app.yaml

-Cで展開先ディレクトリを指定すると、そのディレクトリの配下に展開される。

$ mkdir extract
$ tar -xzf myproject.tar.gz -C extract
$ find extract -type f
extract/myproject/README.md
extract/myproject/src/main.go
extract/myproject/config/app.yaml

myproject.tar.gz自体はmyproject/という親ディレクトリを含むアーカイブのため、extract/myproject/配下に展開される。extractディレクトリを事前にmkdirしておく必要がある点に注意する。

存在しないディレクトリを指定するとエラーになる

-Cは指定したディレクトリへの移動(chdir)を行うだけであり、ディレクトリの作成までは行わない。存在しないディレクトリを指定すると、展開処理は実行されずエラーになる。

$ tar -xzf myproject.tar.gz -C notexist
tar: notexist: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

-Cで指定するディレクトリは、tarコマンドを実行する前にmkdir -pなどで作成しておく。

作成時に -C でアーカイブ内のパスを揃える

-Cは展開(-x)だけでなく作成(-c)時にも使える。作成時に-Cを使うと、指定したディレクトリへ移動してからアーカイブを作成するため、アーカイブ内のパスをフルパスに依存させず、カレントディレクトリからの相対パスに揃えられる。

$ tar -czf archive.tar.gz -C /path/to/myproject .
$ tar -tvf archive.tar.gz
./
./README.md
./src/
./src/main.go
./config/
./config/app.yaml

-C /path/to/myprojectを指定せずにtar -czf archive.tar.gz /path/to/myprojectのようにフルパスを直接渡すと、アーカイブ内のパスにもpath/to/myproject/という余分な階層が含まれてしまう。-Cで対象ディレクトリへ移動してから.を指定することで、アーカイブ内のパスの先頭階層をそろえられる。

-C を複数回指定して異なる場所のファイルをまとめる

GNU tarでは-Cを複数回指定できる。指定するたびにそのディレクトリへ移動するため、異なる場所にあるファイルを1つのアーカイブにまとめられる。

$ tar -czf combined.tar.gz -C /tmp/dirA fileA.txt -C /tmp/dirB fileB.txt
$ tar -tvf combined.tar.gz
fileA.txt
fileB.txt

-C /tmp/dirA/tmp/dirAへ移動してfileA.txtを追加した後、-C /tmp/dirB/tmp/dirBへ移動してfileB.txtを追加している。

相対パスで複数指定する場合の注意点

2つ目以降の-Cに相対パスを指定すると、直前の-Cで移動した先からの相対パスとして解釈される。

$ tar -czf combined.tar.gz -C dirA fileA.txt -C dirB fileB.txt
tar: dirB: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

-C dirAでカレントディレクトリからdirAへ移動した後、続く-C dirBdirAから見たdirBdirA/dirB)として解釈される。カレントディレクトリ直下のdirAdirBをまとめたい場合、dirA/dirBは存在しないためエラーになる。異なる場所のディレクトリを-Cで組み合わせる場合は、絶対パスで指定するか、直前の-Cからの相対パスであることを踏まえてパスを組み立てる。

関連記事