Linuxでcpioアーカイブを作成および抽出する方法の例
cpioアーカイブユーティリティは、現在ではtarのような他のアーカイブツールよりも使用されることが少なくなっていますが、Linux上のinitramfsイメージや、主にRed Hat系のディストリビューションで使用されるrpmパッケージを作成するために依然として使われているため、どのように機能するかを知っておくことは良いことです。このチュートリアルでは、GNU cpioユーティリティを使用してcpioアーカイブを作成および抽出し、それらに含まれるファイルのリストを取得する方法を見ていきます。
このチュートリアルでは、あなたが学ぶことができることは:
- cpio ユーティリティの基本
- cpioアーカイブを作成し、必要に応じて圧縮する方法
- cpioアーカイブを抽出する方法
- cpioアーカイブに含まれるファイルの一覧を取得する方法
使用されるソフトウェア要件と規約
cpioの紹介
Cpio は「Copy In and Out」の略です。すでに述べたように、これはアーカイブユーティリティで、通常はすべての Unix および Unix ライクなオペレーティングシステム(Linux を含む)に含まれています。Cpio には主に「Copy-out」と「Copy-in」の2つの使用モードがあります。前者のモードでは、アプリケーションは標準入力からファイル名のリストを読み取り、デフォルトでは標準出力にアーカイブを作成します。後者のモードでは、アーカイブからファイルをコピーします。別のモードとして「copy-pass」も存在しますが、このチュートリアルではそれについては触れません。
アーカイブを作成する(コピー出力モード)
Cpioにはディレクトリツリーを探索する能力がないため、tarを使用するのとは異なり、ディレクトリを引数として渡してcpioがその内容を再帰的に含むアーカイブを作成することを期待することはできません。代わりに、「一つのことを行い、うまく行う」というUnixの精神に従って、アーカイブに含めるファイルのリストを作成するためにfindのような別のユーティリティを使用する必要があります。例を見てみましょう。
私たちのホームディレクトリの内容でcpioアーカイブを作成したいとします。ここに私たちが実行できるコマンドがあります:
find "$HOME" -depth -print0 | cpio -ocv0 > /tmp/archive.cpio上記で行ったことを分析してみましょう。私たちは find ユーティリティを使用して、アーカイブに含めるべきファイルのリストを取得しました。ユーティリティの最初の引数として、アーカイブする必要のある内容の ディレクトリのパス を渡し、2つのオプション -depth と -print0 を使用しました。前者は find の動作を変更し、各 ディレクトリの内容がディレクトリ自体の前に処理されるようにします;なぜこれが必要なのでしょうか?
ファイルとディレクトリが通常どおり(上から下へ)findによって処理され、読み取り専用のディレクトリがあるとします。このディレクトリが含まれるファイルの前に処理されると、先にアーカイブに追加され、要求されたときに先に抽出されます。cpioにはファイルとディレクトリの権限を管理する能力がなく、ディレクトリが読み取り専用であるため、復元されるときにはその中にファイルをコピーすることが不可能になるでしょう。
-print0オプションを使用することで、代わりに完全なファイル名が標準出力に出力され、標準の改行の代わりにヌル文字で区切られるようにしました。これは、名前に改行を含むファイルも含めることができる対策です。
私たちは、findの出力をcpioの標準入力にパイプし、リストにあるファイルがアーカイブに含まれるようにしました。cpioを実行する際には、-o、-v、-c、および-0のオプションを使用しました。最初のオプションは--createの短縮形であり、cpioを「コピーアウト」モードで使用することを指定するために必要です。-vオプション(--verbose)は、アプリケーションによって処理されているファイルのリストを表示するために使用され、-cでcpioのフォーマットを指定しました。 アーカイブを作成するためにコピーアウトモードで実行する場合、デフォルトでは非常に古い「bin」形式が使用されます。-cを使用することは基本的に-H newcのショートハンドであり(-Hオプションはcpio形式を指定することを可能にします)、これによりcpioは新しいSVR4ポータブル形式を使用するようになります。最後に、-0オプションを使用しました。これは--nullの短縮形です。この最後のオプションは、リスト内のファイルがヌル文字で区切られていることを指定するために使用されます。
私たちが最後に行ったことは、cpioの出力をファイルにリダイレクトすることであり、そのアーカイブを驚くことに/tmp/archive.cpioと名付けました(ファイル拡張子は完全に任意です)。この最後のリダイレクトの代わりに、cpioの-Fオプション(--file)を使用し、ファイル名を引数として指定することで、アプリケーションに標準出力の代わりにそれに書き込むように指示することもできました。
アーカイブを作成する際に圧縮が必要な場合はどうすればいいでしょうか?私たちは、cpioの標準出力をファイルを圧縮するために特別に設計された他のアプリケーションに渡すために別のパイプを使うことができます。例えば、gzipを使います。我々はこう書くことになります:
find "$HOME" -depth -print0 | cpio -ocv0 | gzip -9 > /tmp/archive.cpio.gzアーカイブを抽出しています(コピーインモード)
私たちは今、cpioアーカイブを作成する方法を見ましたが、次はそれを抽出する方法を見てみましょう。最初に言うべきことは、コピーアウトモードではデフォルトの「bin」以外の形式を使用したい場合、アーカイブ形式を指定する必要があるのに対し、抽出時には形式が自動的に認識されるということです。
コピーインモードでcpioを実行するには、-iオプションを指定してcpioユーティリティを起動します。これは--extractの短縮形です。このモードで作業する際は、アーカイブをcpioの標準入力として渡す必要があります。以下は、前に作成したアーカイブを抽出する方法です。
cpio -iv < /tmp/archive.cpioこのコマンドを実行すると、アーカイブに保存されたファイルが現在の作業ディレクトリに抽出されます。ファイルの新しいバージョンまたは同じバージョンがすでにファイルシステムに存在する場合、cpioはそれらの抽出を拒否し、以下のようなエラーを返します:
<file> not created: newer or same age version exists
実際の抽出を行う前に別の場所に切り替えたい場合、-Dオプション(--directoryの短縮形)で指定するだけで済みます。
コピーモードで作業するのと同様に、-Fオプションを使用し、ファイル名を引数として指定することで、cpioに標準入力以外のファイルから読み込むよう指示できます。
抽出したいアーカイブが圧縮されている場合はどうしますか?gzipで圧縮したアーカイブを抽出したいと仮定すると、最初に圧縮データを読み取り、それをcpioにパイプする必要があります。gzip圧縮ファイルの場合、zcatユーティリティを使用してその作業を行うことができます:
zcat /tmp/archive.cpio.gz | cpio -ivcpio アーカイブに含まれるファイルの一覧表示
cpioアーカイブ内のファイルリストを抽出することなく取得するのは非常に簡単です。-tオプション、つまり--listの短縮形式と一緒にアプリケーションを実行するだけで十分です。このチュートリアルの最初のセクションで作成したアーカイブ内のすべてのファイルをリストするには、次のように実行します:
cpio -t < /tmp/archive.cpioそのコマンドは、アーカイブに保存されているファイルのリストを生成します。これにオプションとして -v を追加すると、ファイルとディレクトリの権限が含まれる ls -l の出力に似た出力が得られます。
結論
この記事では、Linuxでcpioユーティリティを使用する方法について学びました。現在はtarよりも使用頻度が低いですが、特定の目的、例えばrpmソフトウェアパッケージを作成するために依然として使用されているため、その仕組みを知っておくことが重要です。アーカイブの作成、抽出、最後にその内容をリストする方法を見ました。
