Linux - パッケージングとアンパッケージング（tar）


# パッケージングとアンパッケージング

## tar
tar とは Tape ARchive の略で、ディレクトリや複数のファイルを1つのファイルにまとめてアーカイブすることができます。
元々は圧縮機能を持っていませんが、オプションを使用して適切な圧縮コマンドを呼び出して圧縮を行うことができます。
このコマンドはファイル属性を保持することができるので、推奨されます。
対応するファイルは `.tar` 拡張子です。

### 形式：
```shell
tar [OPTION...] [FILE]...
# tar {A|c|d|r|t|u|x}[GnSkUWOmpsMBiajJzZhPlRvwo] [ARG...]
```

### UNIX スタイルの書き方
```shell
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 スタイルの書き方
```shell
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...]
```

### よく使うオプション
必須オプション：`{A|c|d|r|t|u|x}`
```shell
-A|--catenate|--concatenate # tar ファイルをアーカイブに追加
-c|--create # 新しいアーカイブを作成
-d|--diff|--compare # アーカイブとファイルシステムの差異を確認
--delete # アーカイブから削除（テープでは不可）
-r|--append # アーカイブの末尾にファイルを追加
-t|--list # アーカイブの内容をリスト
--test-label # アーカイブラベルをテストして終了
-u|--update # アーカイブ内のコピーよりも新しいファイルを追加
-x|--extract|--get # アーカイブからファイルを抽出
```

#### -f オプション
```shell
-f|--file=ARCHIVE # 圧縮ファイルを指定、ほとんどの場合必須
```

#### OPTIONS オプション
```shell
# OPTIONS オプション [GnSkUWOmpsMBiajJzZhPlRvwo], 位置に注意
-G|--incremental # 古い GNU フォーマットのインクリメンタルバックアップを処理
-n|--seek # アーカイブを検索可能にする
-S|--sparse # スパースファイルを効率的に処理
-k|--keep-old-files # 展開時に既存のファイルを上書きしない
-U|--unlink-first # 展開前にリンクを削除
-W|--verify # 書き込み後にアーカイブを検証
-O|--to-stdout # ファイルを標準出力に展開
--to-command=COMMAND # 展開したファイルをパイプで他のプログラムに送る
-m|--touch # ファイルのタイムスタンプを変更しない
-p|--preserve-permissions|--same-permissions # ファイルパーミッションを保持
-s|--preserve-order|--same-order # アーカイブ内のファイル順序に従って列挙
-M|--multi-volume # 複数のアーカイブボリュームを作成/リスト/展開
-B|--read-full-records # 読み取り時に再度ブロック化
-i|--ignore-zeros # アーカイブ内のゼロバイトブロックを無視
-a|--auto-compress # アーカイブの拡張子に基づいて圧縮プログラムを決定
-j|--bzip2 # bzip2 で圧縮/解凍
-J|--xz # xz で圧縮/解凍
--lzip|--lzma|--lzop # lzip|xz --format=lzma|lzop
-z|--gzip|--gunzip|--ungzip # gzip で圧縮/解凍
-Z|--compress|--uncompress # compress で圧縮/解凍
-h|--dereference # シンボリックリンクを実体に変換
--hard-dereference # ハードリンクを実体に変換
-P|--absolute-names # ファイルパスの先頭スラッシュを保持
-l|--check-links # リンクされていないファイルのみ表示
-R|--block-number # 各情報にアーカイブ内のブロック番号を表示
-v|--verbose # 詳細情報を表示
-w|--interactive|--confirmation # 操作ごとに確認
-o # 古い V7 tar フォーマットを使用
```

#### 圧縮オプション
```shell
-z # gzip 圧縮ツールを使用
-j # bzip2 圧縮ツールを使用
-J # xz 圧縮ツールを使用
```

#### その他のオプション
```shell
--show-defaults # tar のデフォルトオプションを表示
--exclude # ファイルを除外
-C|--directory=DIR # ディレクトリを指定
-T|--files-from=FILE # 処理するファイルをファイルから読み込む
-X|--exclude-from=FILE # 除外するファイルをファイルから読み込む
--version # バージョンを表示
```

#### デフォルトで相対パスを使用
```shell
[root@rocky86 0726]# tar -cf etc.tar /etc
tar: Removing leading `/' from member names
```

#### パスを保持する
```shell
[root@rocky86 0726]# tar -cPf etc2.tar /etc
```

#### 例：単なるパッケージ化で、圧縮しない場合
```shell
[root@rocky86 0726]# tar -cvf test.tar f1.txt f2.txt
f1.txt
f2.txt
```

#### 再帰的にディレクトリをパッケージ化
```shell
[root@rocky86 0726]# tar -cvf log.tar /var/log
```

#### サイズが同じ
```shell
[root@rocky86 0726]# du -sh /var/log/
13M /var/log/
[root@rocky86 0726]# ll -h log.tar
-rw-r--r-- 1 root root 13M Jul 26 15:57 log.tar
```

#### 例：ディレクトリ内のファイルのみをパッケージ化し、ディレクトリ自体は含まない
```shell
[root@rocky86 ~]# cd /etc/
[root@rocky86 etc]# tar -cf etc.tar *
# 先にディレクトリを指定
[root@rocky86 ~]# tar -C /etc/ -cf etc.tar ./
```

#### 例：追加と削除（圧縮ファイルへの追加はサポートされていない）

```shell
[root@rocky86 0726]# tar -tvf test.tar
-rw-r--r-- root/root 4453 2022-07-26 15:19 f1.txt
-rw------- root/root 1946847 2022-07-26 14:09 f2.txt
```

#### 追加
```shell
[root@rocky86 0726]# tar -rf test.tar f3.txt passwd
[root@rocky86 0726]# tar -tvf test.tar
-rw-r--r-- root/root 4453 2022-07-26 15:19 f1.txt
-rw------- root/root 1946847 2022-07-26 14:09 f2.txt
-rw------- root/root 1814952 2022-07-26 14:09 f3.txt
-rw-r--r-- root/root 2858 2022-07-25 22:09 passwd
```

#### 削除
```shell
[root@rocky86 0726]# tar --delete -vf test.tar f1.txt f2.txt
[root@rocky86 0726]# tar -tvf test.tar
-rw------- root/root 1814952 2022-07-26 14:09 f3.txt
-rw-r--r-- root/root 2858 2022-07-25 22:09 passwd
```

#### test1.tar 内のファイルを抽出して再パッケージ化し、test1.tar 内のファイルは削除しない
```shell
[root@rocky86 0726]# tar -A test.tar -f test2.tar
```

#### 例：パッケージ内のファイルをリスト
```shell
[root@rocky86 0726]# tar -tvf test.tar
-rw------- root/root 1814952 2022-07-26 14:09 f3.txt
-rw-r--r-- root/root 2858 2022-07-25 22:09 passwd
```

#### 例：パッケージを展開
```shell
[root@rocky86 0726]# tar -xf log.tar
# ディレクトリを指定
[root@rocky86 0726]# tar -xf log.tar -C /tmp
```

#### 例：パッケージを作成し、圧縮
```shell
[root@rocky86 0726]# tar -zcvf etc.tar.gz /etc/
[root@rocky86 0726]# tar -jcvf etc.tar.bz2 /etc/
[root@rocky86 0726]# tar -Jcvf etc.tar.xz /etc/
[root@rocky86 0726]# ll -h etc.tar.*
-rw-r--r-- 1 root root 4.7M Jul 26 16:37 etc.tar.bz2
-rw-r--r-- 1 root root 6.4M Jul 26 16:36 etc.tar.gz
-rw-r--r-- 1 root root 4.0M Jul 26 16:37 etc.tar.xz
[root@rocky86 0726]# tar -xf etc.tar.gz -C /tmp/etc-gz/
[root@rocky86 0726]# tar -xf etc.tar.bz2 -C /tmp/etc-bz2/
[root@rocky86 0726]# tar -xf etc.tar.xz -C /tmp/etc-xz/
```

#### 例：指定ファイルから打包するファイルを読み込む
```shell
[root@rocky86 0726]# cat list.txt
f1.txt
f2.txt
[root@rocky86 0726]# tar -zcvf x.tar.gz -T list.txt
f1.txt
f2.txt
```

#### 例：除外と含める

```shell
# 除外するファイルを指定
[root@rocky86 ~]# tar zcvf /root/a.tgz --exclude=/app/host1 --exclude=/app/host2 /app
```

#### ファイルから読み取る
```shell
[root@rocky86 ~]# tar zcvf mybackup.tgz -T /root/includefilelist -X /root/excludefilelist
```

#### 例：デフォルトオプションを表示
```shell
[root@rocky86 0726]# tar --show-defaults
--format=gnu -f- -b20 --quoting-style=escape --rmt-command=/etc/rmt --rsh-command=/usr/bin/ssh
```