RPMパッケージやAppleの"pax"インストーラ, Linux kernel 2.6でのinitramfsに使われていたりと、何気なく現役で使われている。
というわけで、例によって自分用メモ。
GNU cpio HTML ドキュメントにもTutorialが用意されており、基本は「Copy-out:アーカイブ作成」「Copy-in:アーカイブ展開」「Copy-pass:ディレクトリ単位でコピー」の3つのモードを使い分ける。
cpio {-o|--create} その他オプション < 対象ファイル一覧 > アーカイブファイル
標準入力でファイル名の一覧を与えると、標準出力にアーカイブデータを出力する。findコマンドを組み合わせると使いやすくなる。
$ find . -print | cpio -ov > foo.cpio
パイプでつなげれば、gzip圧縮もできる。拡張子としては".cpio.gz"や".cpgz"が使われるようだ。
$ find . -print | cpio -o | gzip > foo.cpio.gz
cpio {-i|--extract} その他オプション < アーカイブファイル
標準入力でアーカイブデータを与えると、アーカイブの展開を行う。
$ cpio -iv < foo.cpio
"-t"オプションを指定すると、実際の展開は行わず入力ファイル名の一覧を表示するだけとなる。
$ cpio -t < foo.cpio
cpio {-p|--pass-through} その他オプション コピー先ディレクトリ名 < 対象ファイル一覧
例:
$ cd <src_dir> $ find . -print | cpio -pvd <dest_dir>
"-d"オプションをつけておくと、"<dest_dir>"が存在しない場合は自動的に作成してくれる。
ファイル名に改行を含むファイルをアーカイブしたい場合は、"-0"または"--null"で、ファイル名の一覧がNULL区切りであることを指示しておく。
同時に、findコマンドでファイル名をNULL区切りにするよう"-print0"を使う。
$ find . -print0 | cpio -ov0 > foo.cpio $ find . -print0 | cpio --null -ov > foo.cpio
GNU cpio HTMLドキュメントのTutorialを読んでいたら、findコマンドに"-depth"オプションをつけた例がある。
find . -print -depth | cpio -ov > tree.cpio
これについて実際に実験してみて、「何故 "-depth" 付を推奨しているのか」分かったのでメモ。ちなみにCentOS 5.2 の GNU find 4.2.27 を使うと、"-print -depth"の順にするとwarningが出てしまったので、以降は"-depth -print"の順にしている。
まず、"-depth"オプション(or "-d")を指定すると「ディレクトリ階層が深い方を優先して処理する」ようになる。
例:
$ cd cpio_test/ $ find . . ./foo ./foo/bar ./foo/bar/test3.txt ./foo/test2.txt ./test1.txt $ find . -depth ./foo/bar/test3.txt ./foo/bar ./foo/test2.txt ./foo ./test1.txt .
これとcpioを組み合わせ、展開した時の動作を考えてみる。
このため、"-depth"有りで作成されたcpioアーカイブを展開する時は
cpio -i < foo.cpio
ではなくて、"-d"でディレクトリの自動作成を有効にした上で展開する必要がある。
cpio -id < foo.cpio
もし"-d"を使わない場合は、予めディレクトリだけは作成しておく必要がある。
わざわざ"-depth"有りの動作を使う理由は、ディレクトリの権限が特殊な場合を想定しているからである。
一番分かりやすい例だと、そのディレクトリ権限の所有者bitから"w"が落ちている場合である。
$ cd cpio_test/ $ find . | xargs ls -ld drwxrwxr-x 3 msakamoto msakamoto 4096 11月 18 19:07 . drwxrwxr-x 3 msakamoto msakamoto 4096 11月 18 19:09 ./foo dr-x------ 2 msakamoto msakamoto 4096 11月 18 19:14 ./foo/bar ^ "test3.txt"を作成後に、chmod u-w して"w"権限を落としている。 -rw-rw-r-- 1 msakamoto msakamoto 10 11月 18 19:14 ./foo/bar/test3.txt -rw-rw-r-- 1 msakamoto msakamoto 6 11月 18 19:08 ./foo/test2.txt -rw-rw-r-- 1 msakamoto msakamoto 6 11月 18 19:08 ./test1.txt
この場合に、"-depth"無しでアーカイブしたcpioを展開すると、"foo/bar/test3.txt"が展開できなくなる。
実際にやってみる:
$ cd cpio_test/ $ find . -print | cpio -o > ../test1.cpio $ cd ..; mkdir test1; cd test1 $ cpio -iv < ../test1.cpio . foo foo/bar cpio: foo/bar/test3.txt: 許可がありません foo/bar/test3.txt foo/test2.txt test1.txt 1 block
こういう場合に "-depth"有りでアーカイブしておけば、中のファイルツリーを展開した後で権限を復元するようになるので、問題は発生しなくなる。
実際にやってみる:
$ cd cpio_test/ $ find . -depth -print | cpio -o > ../test2.cpio $ cd ..; mkdir test2; cd test2 $ cpio -ivd < ../test2.cpio # ← "-d"オプションを忘れずに! foo/bar/test3.txt foo/bar foo/test2.txt foo test1.txt . 1 block