2010年03月19日
cpコマンドの -l オプションでディスク使用量を節約
今回はDebianのソースパッケージのビルドスクリプトの中に使われていた小技を紹介します。
Linuxカーネルのソースコードはいまや1000万行を超えています。
カーネルのソースアーカイブをダウンロードしてくるとそれだけの規模のソースコードをディスクに置くことになります。
同じカーネルのソースからいくつか違ったコンフィグでビルドしたいときがあります。例えば私の場合だとARMのversatileボード用とrealview用など。
これをひとつのディレクトリでやろうとすると切り替えのたびにmake mrproper として消す必要があります。
カーネルのソースツリーをまるごとコピーすればよいのですが、ディスクの容量を消費するし、コピーにもそれなりの時間がかかります。
(2010.10.12追記。その場合にはこっちのほうがおすすめ。)
そんなときにちょうどいいのが、cpコマンドの-lオプションです。
$ tar xvf linux-2.6.33.tar.bz2 $ cp -al linux-2.6.33 linux-2.6.33_versatile $ cp -al linux-2.6.33 linux-2.6.33_realview
この-lオプションでは実際にコピーする代わりにリンク(ハードリンク)を作ります。つまりファイルの実体にもうひとつのファイル名をつけるわけです。なので、ディスクの容量の消費も実体も含めてコピーするのに比べたら少なくて済みますし、コピーの時間もそれほどかかりません。
リンクされているファイルは書き込みがあったら自動的に分離するので、普段は気にする必要がありません。
(追記: これは私の誤解でした。)
全体のサイズは大きいけど、コピーしてほんの一部しか書き換えない元のファイルを書き換えず、新たにファイルを追加するだけの場合に限って効果的だと思います。 このページでもさりげなくこの小技でカーネルソースをコピーしていました。
なお、マニュアルを見るとcpの-sオプションではシンボリックリンクが作れるようです。
ハードリンクとシンボリックリンクの比較はこちら。
ソースツリーを複製する用途にはハードリンクの方が向いているようです。ただし、このハードリンクは同一のファイルシステム間でしか使えないという制限があるので注意してください。
.
.
(追記)誤解したまま記事を書いていました。ファイルの書き換えが他のディレクトリに影響するとなるとかなり気をつけなければならないので、人間がファイルを編集する可能性ある場面では全然実用的ではないですね。処理内容が決まっているスクリプトに限定された小技でした。
関連するページ
トラックバックURL
コメント一覧
一般的な(POSIX)のhard linkにはそういうcopy-on-write的な機能はないと思いますが…。
Linuxでそういうのを実現するpatchはあったみたいですが、セマンティクスが変わっちゃうので採用されなかったと思います。
これは私の思い込みでした。
今、リンクされたファイルをエディタで書き換えたら他方のファイルも同じように書き変わっていました。
Debianのソースパッケージのビルドではcp -al で複数のコピーを作ってそれぞれ別のパッチをあててコンフィグしてビルドしているのですが、これは既存のファイルを書き換えることなく全てファイルの追加で行われているから大丈夫という高度に計算されたものだったのですね。
する script がついていることを思い出しました。我田引水失礼しました。
マニュアルによれば、cpコマンドの-sオプションではシンボリックリンクを作ってくれるようですね。