技術

tarコマンドを使いこなそう! Unix版とGNU版の違い

普段、適当に使いがちなtarコマンド、以外と奥が深いです。

展開ならGUIでもできるので、以外と知らなくてもなんとかなります。ただ、エンジニアなら使いこなせるようになっておきたいコマンドでもあります。

というわけで、tarについてまとめてみました。

圧縮とアーカイブの違い

tarを使う時は、圧縮とアーカイブの違いを把握しておく必要があります。

圧縮は、ファイルサイズを縮小することです。可逆的でサイズを元に戻すことができます。このことを解凍と言います。

アーカイブは、複数ファイルを1つにまとめることです。このとき、ファイルサイズの縮小はありません。まとめたファイルを複数に戻すことを、展開とかアンアーカイブと呼びます。

普及しているzipは、圧縮兼アーカイブです。また戻すときは解凍兼アンアーカイブになります。このため、圧縮とアーカイブは同じことだと誤解しやすくなります。

一般ユーザーならこの認識でも問題ないのですが、エンジニアはこの違いは分かっておいた方がいいでしょう。

そして、tarコマンドもオプションとの組み合わせて、アーカイブ/アンアーカイブと圧縮/解凍を同時のこなします。この辺がややこしいところです。

Unix版とGNU版の2つがある

tarコマンドにはUnix版とGNU版の2つがあります。挙動が微妙に違うので、自分がどちらを使っているか、把握しておくことが重要です。

MacだとUnix版、WindowsのWSLだとGNUになっているかと思います。

–versionオプションでどちらを使っているか、わかります。

Unix版の場合は、bsdtarと表示されます。

% tar --version
bsdtar 3.5.1 - libarchive 3.5.1 zlib/1.2.11 liblzma/5.0.5 bz2lib/1.0.8

GNU版の場合は、 (GNU tar) と表示されます。

% gtar --version
tar (GNU tar) 1.34
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by John Gilmore and Jay Fenlason.

MacでもGNU版を使うことができる

MacでもGNU版を使うことができます。

brew install gnu-tar

でインストールできます。

GNU版のtarのコマンドはgtarになります。

GNU版の方が使いやすいですし、業務でlinuxやWindowsと挙動を会わせたほうがいいこともあるので、入れておいた方がいいかと思います。

よく使うオプション

tarコマンドを使うときはオプションが多くなりがちです。だいたい、xzvfのセットで使うので、一つ一つの意味は覚えていない人も多いかと思います。

しかし、やはり覚えておいたが方がいいでしょう。各オプションは以下の通りです。

  • f
    ファイル指定。このオプションなしでtarコマンドを使うケースは、バージョン確認以外で思いつかないです。

  • z
    ファイルの圧縮形式です。zはgzipで、拡張子はtar.gzになります。他の圧縮形式のオプションは必要なときググればいいですが、gzipは一番使うのでこれは覚えておいた方がいいです。

  • v
    詳細表示オプションです。vオプション=詳細表示は、tar以外のコマンドでもよく使われるオプションです。

  • x
    アンアーカイブするときに使うオプションです。tar.gzファイルを展開するときに使うケースがほとんどです。

以上が、よく使うオプションになります。それ以外にも知っておいた方がいいオプションは以下です。

  • c
    圧縮するときに使うオプションです。cvzfのセットで使うことがほとんどです。xzvfがtar.gzの展開、cvzfがtar.gzにアーカイブすると覚えておいていいでしょう。後述しますが、Unix版とGNU版によって、挙動が違うので注意が必要です。

  • t
    アーカイブされたファイルの中身を、展開しないで確認するオプションです。tfの組み合わせて使用します。

アーカイブ時の隠しファイルに注意

Unix版とGNU版には、いくつか違いがあるのですが個人的にはまりポイントは、cオプションのアーカイブの挙動かと思います。

Unix版とGNU版で同じオプションでtar.gzファイルを生成したとき、Unix版の方がファイルサイズが大きくなります。これはUnix版の方は、メタファイルが隠しファイルとして入るからです。

さらにややこしいことに、この隠しファイルはtar xzvfで展開したときは、なくなります。ただし、プログラミング言語の挙動によっては、隠しファイルが出てきたりします。

この挙動の違いで、アンアーカイブして各ファイルに処理をしていくシステムでバグが出たことがありました。

Unix版でも、manページにはありませんが、以下のオプションを付ければ隠しファイルなしでアーカイブすることができます。

tar --disable-copyfile --format ustar -cvzf {{アーカイブファイル名}} {{アーカイブ対象ファイル名}}

ハンズオン

というわけでこの挙動を実際に見てみます。

ここからサンプルデータをいくつかダウンロードします。

今回ダウンロードしたデータは以下の通りです。

これを比較のため、以下の3パターンでアーカイブしてみました。

  • tar Unix版
  • tar Unix版 disable-copyfileオプションあり
  • tar GNU版

結果は以下の通りです。tar Unix版だけサイズが少し大きいです。

ちなみtfオプションで中身を見ても、隠しファイルは見えません。

% tar -tf normal.tar.gz 
airtravel.csv
cities.csv
example.csv

tar czvfで展開し、ls -aオプションでも見えません。

これを以下のPythonのプログラムで展開してみます。

import tarfile

with tarfile.open("normal.tar.gz") as tar:
    tar.extractall(path="archived_normal")

with tarfile.open("normalop.tar.gz") as tar:
    tar.extractall(path="archived_normalop")

with tarfile.open("gtar.tar.gz") as tar:
    tar.extractall(path="archived_gtar"

結果は以下のとおりです。Unix版tarのdiable-copyfileオプションなしだけ、隠しファイルが出てきました。

以上で検証は終了です。

この隠しファイルがあってもいいことはないので、データ作成時はGNU版を使った方がいいと思います。

まとめ

以上、tarコマンドについてでした。

最近、Unix版の隠しファイルの仕様ではまったので、今回、まとめてみました。