cpio の使い方

# cpio
tar は各所で必要に応じて拡張され、様々な形式が存在して互換性の無い状態になっています。
~~よって、互換性の問題を解決するために POSIX で cpio フォーマットが定義されました。(cpio コマンド自体は tar より古くからあったが、有名でないため亜種が無かった)~~
また、cpio も各所で拡張され互換性が無くなっており POSIX 標準から外れたため亜種が増える、廃れる可能性も高いフォーマットです[^1]。現在の規格では pax コマンドが標準となっており、pax コマンドである程度の tar や cpio アーカイブが使えるようになっています。
が、cpio の使い方。すぐ忘れるので忘備録。

[^1]: tar と cpio は POSIX.1-1988 (ISO/IEC 9945-1:1996) で登録されたが POSIX.1-2001 (IEEE Std 1003.1-2001) で規格から削除。[bsdcpio.1](https://opensource.apple.com/source/libarchive/libarchive-14/libarchive/doc/text/bsdcpio.1.auto.html) [「大岡裁き」ならぬ「POSIX裁き」](http://richlab.hatenablog.com/entry/2016/12/09/043046)

# アーカイブの作成 (コピーアウトモード)
## 基本の書式 (マニュアル)
```tcsh:cpio
$ cpio -o < file_list > archive_file
$ tar cf archive_file file1 file2 file3...
$ pax -w -f archive_file file1 file2 file3...
```

## 通常の使用方法
```tcsh:cpio
$ ( cd dir ; find . -print0 | cpio -o -a0v ) | p7zip -c > archive_file.cpio.7z
```
アーカイブにフルパスを含めないようにサブシェル内で cd で移動して、find でファイルリストを作成。
-print0 で、ファイルの区切りを NULL にすることで色々なファイル名、ディレクトリ名があっても問題が出ないようにする。
cpio -o で、cpio アーカイブを出力。 -0 で NULL 区切りのファイル名一覧を受け取る。v で処理中のファイル名を表示。

```tcsh:pax
$ ( cd dir ; find . -print0 | pax -0wv ) | p7zip -c > archive_file.pax.7z
```
pax も同様 -0 で NULL 区切りでファイル名を受け取り、-w でアーカイブを作成。-v で処理中のファイル名を出力。

# アーカイブの中身を確認
```tcsh:cpio&nbsp;&amp;&nbsp;tar&nbsp;&amp;&nbsp;pax
> p7zip -c -d archive_file.cpio.7z | cpio -t
> p7zip -c -d archive_file.tar.7z | tar tf -
> p7zip -c -d archive_file.pax.7z | pax 
```
ファイルの一覧を表示して目的のファイルが入っているか確認。

# アーカイブの展開 (コピーインモード)
## 基本の書式 (マニュアル)
```tcsh:
$ cpio -i < archive_file
$ tar xf archive_file
$ pax -r < archive_file
```

## 通常の使用方法
```tcsh:cpio
$ p7zip -c -d archive_file.cpio.7z | cpio -iv
```

```tcsh:tar
$ p7zip -c -d archive_file.tar.7z | tar xvf -
```

```tcsh:pax
$ p7zip -c -d archive_file.tar.7z | pax -rv
```

# ディレクトリのコピー

```tcsh:cpio
$ cd /from-dir
$ find . -depth -print0 | cpio -0pdmvu /to-dir
```

```tcsh:tar
$ (cd /from-dir; tar cf - . ) | (cd /to-dir; tar xvf -) 
```

```tcsh:pax
$ ( cd /from-dir ; pax -rwv . /to-dir )
或いは
$ pax -r -w -v -s '@/from-dir/@@' /from-dir /to-dir
```
2 つ目は、/usr/bin を /usr/local/bin にコピーする場合、

$ pax -r -w **/usr**/bin /usr/local

とすると、コピー先が /usr/local&#8203;**/usr**/bin となってしまう。
なので -s でパス名を置換して頭の **/usr** を外し、/bin/～ というパス名でコピー。

$ pax -r -w -s '@**/usr**@@' **/usr**/bin /usr/local

手でたたくなら 1番目の方法が、Shell スクリプトにするなら 2番目の方法が便利だともいます。

# tar の形式
様々な形式といっても、どんな形式があるのか。

|形式|最大uid|ファイルサイズ|ファイル長|デバイス番号|
|:--:|:--:|:--:|:--:|:--:|
|gnu        |$(2^{64}\simeq) 18\times10^{19}$|無制限|無制限|63 bits|
|oldgnu     |$(2^{64}\simeq) 18\times10^{19}$|無制限|無制限|63 bits|
|v7         |$2097151$|8GB|99|なし|
|POSIX ustar|$2097151$|8GB|256|21 bits|
|POSIX pax  |無制限|無制限|無制限|無制限|

FreeBSD マニュアル [tar(5)](http://www.koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=tar&dir=jpman-12.0.2%2Fman&sect=5)、
GNU [Tar Info](https://www.gnu.org/software/tar/manual/html_section/tar_67.html#Formats)
Solaris 8 の tar ヘッダ [archives(4)](https://docs.oracle.com/cd/E19455-01/816-3327/6m9k7qvec/index.html#archives-4-indx-1)

## tar の圧縮ファイルの伸張
```tcsh:
> tar axvf archive.7z
```
GNU の tar だと a フラグで圧縮形式を自動判別して伸張、tar アーカイブの展開をしてくれます。

## tar ファイルの圧縮
```tcsh:
> tar acf loopstats.tar.gz loopstats.2019??
> tar jcf loopstats.tar.bz2 loopstats.2019??
> tar --lzip -cf loopstats.tar.lzip loopstats.2019??
> tar --xz -cf loopstats.tar.xz loopstats.2019??
> tar Jcf loopstats.tar.xz loopstats.2019??
> tar cf - loopstats.2019?? | p7zip -c > loopstats.tar.7z
> ls -ltr loop*
-rw-r--r-- 1  111  115 23162257 Oct  6 15:52 loopstats.201909
-rw-r--r-- 1  111  115 13301935 Oct  6 15:52 loopstats.201910
-rw-rw-rw- 1 root root 11652950 Oct  6 18:03 loopstats.tar.gz
-rw-rw-rw- 1 root root  9465052 Oct  6 18:03 loopstats.tar.bz2
-rw-rw-rw- 1 root root  8038923 Oct  6 18:04 loopstats.tar.lzip
-rw-rw-rw- 1 root root  8042628 Oct  6 18:04 loopstats.tar.xz
-rw-rw-rw- 1 root root  8041735 Oct  6 18:05 loopstats.tar.7z
```
圧縮時は a を指定すると gzip になります。(拡張子は見ない)

|形式| tar オプション |
|--:|:--|
|compress|Z|
|gzip|z|
|xz|J, --xz, --lzma, --lzop|
|bzip2|j, --bzip2|
|lzip|--lzip|
|7zip|なし|