【Linux】cpioコマンドでアーカイブを作成・展開・コピーする

目次

概要

ファイルリストを標準入力から受け取り、アーカイブファイルを作成したり、逆にアーカイブからファイルを展開したりするためのコマンドです。

tar コマンドと似ていますが、cpio は「ファイルパスのリストをパイプで渡す必要がある」というフィルタ型の動作が特徴です。RPMパッケージの内部データ展開や、initramfs(初期RAMディスク)の操作、ディレクトリツリーの効率的な複製(パススルー)などで現在も利用されています。

仕様(引数・オプション)

構文

cpio は以下の3つのモードのいずれかで動作します。

cpio -o [オプション] > [アーカイブファイル]
cpio -i [オプション] < [アーカイブファイル]
cpio -p [オプション] [出力先ディレクトリ] < [ファイルリスト]

動作モード

モード説明
-oCopy-Outモード。ファイルリストを入力として受け取り、アーカイブを作成(出力)します。
-iCopy-Inモード。アーカイブを入力として受け取り、ファイルを展開(抽出)します。
-pPass-Throughモード。アーカイブを作成せず、入力されたファイルを別のディレクトリに直接コピーします。

主なオプション

オプション説明
-d展開時、必要に応じてディレクトリを自動作成します(重要)。
-v処理したファイル名を表示します(Verbose)。
-tアーカイブを展開せず、中身のリストを表示します。
-u既存のファイルを無条件に上書きします。
-mファイルの更新日時を、展開時の時刻ではなく元のファイルの時刻に保持します。
–no-preserve-owner展開したファイルの所有者を、元の所有者ではなく実行ユーザーに変更します。
–null / -0入力ファイルリストの区切り文字を改行ではなくNULL文字として扱います(find -print0 とセットで使用)。
-F [ファイル]標準入出力の代わりに、指定したアーカイブファイルを使用します(リダイレクト不要)。

基本の使い方

カレントディレクトリ内のファイルリストを作成し、それを cpio に渡してアーカイブを作成します。その後、中身を確認します。

# カレントディレクトリの全ファイルをリスト化し、backup.cpio にアーカイブ
find . -depth | cpio -ov > backup.cpio

# アーカイブの中身を確認(展開はしない)
cpio -it < backup.cpio

実行結果例

.
./config.json
./assets
./assets/logo.png
2 blocks

実践コマンド

アーカイブを展開する(ディレクトリ構造を維持)

作成されたアーカイブを元のディレクトリ構造のまま展開します。-d オプションがないとディレクトリが作られずエラーになることがあるため必須です。

# backup.cpio を現在の場所に展開
cpio -ivd < backup.cpio

RPMパッケージ(ソース)の中身を展開する

Red Hat系ディストリビューションで使われる .rpm ファイルは、実はcpio形式で梱包されています。rpm2cpio で変換してからパイプで渡すことで、インストールせずに中身を取り出せます。

# src.rpm をカレントディレクトリに展開
rpm2cpio nginx-1.20.1-1.el8.src.rpm | cpio -idv

ディレクトリツリーを別の場所に丸ごとコピーする(パススルー)

アーカイブファイルを作らずに、あるディレクトリの中身を別のディレクトリへ構造ごと複製します。cp コマンドよりも柔軟な制御が可能です。

# src_dir 以下の全ファイルを dest_dir へコピー
# (find -print0 と cpio --null の組み合わせで、スペース入りファイル名にも対応)
cd src_dir
find . -type f -print0 | cpio --null -pvd ../dest_dir

カスタムポイント

  • ファイル名にスペースが含まれる場合の対策 (–null)ファイル名にスペースや改行が含まれる可能性がある場合、標準のリスト形式では正しく処理できません。必ず find -print0 でNULL区切りのリストを作り、cpio –null で受け取ってください。Bashfind . -print0 | cpio --null -ov > archive.cpio
  • 所有権の変更 (–no-preserve-owner)他人のバックアップを展開する際、元の所有者ID(UID)を維持しようとすると権限エラーになることがあります。このオプションを使うと、展開したファイルの所有者を「コマンドを実行したユーザー」に変更できます。Bashcpio -ivd --no-preserve-owner < system_backup.cpio

注意点

  1. -d オプションの忘れcpio -i で展開する際、-d を付けないと、サブディレクトリが存在しない場合に「ディレクトリが見つかりません」というエラーで展開に失敗します。基本的には常につけることを推奨します。2. 入力リストの作成が必要tar コマンドのように tar cf archive.tar ./dir といった指定はできません。必ず ls や find の結果をパイプで渡す必要があります。
  2. 上書きの挙動デフォルトでは、同名の古いファイルが存在する場合のみ上書きしません。強制的に上書きしたい場合は -u オプションが必要です。

応用

initramfs(初期RAMディスク)イメージの確認と編集

Linuxの起動時に読み込まれる initramfs ファイルも gzip圧縮された cpioアーカイブです。これの中身を確認したり、編集して再作成する際に利用されます。

# initramfsの中身を展開して確認する例
mkdir initramfs_work
cd initramfs_work
zcat /boot/initramfs-linux.img | cpio -idv

まとめ

cpio は、単体で使うよりも find や rpm2cpio と組み合わせて真価を発揮するコマンドです。

日常的なバックアップには tar が使われますが、「RPMの中身を見たい」「特殊なファイルシステムをコピーしたい」「initramfsをいじりたい」といった高度な操作を行う場面で、このコマンドの知識が必要になります。-p モードによるディレクトリコピーは高速で便利なので覚えておくと役立ちます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次