檜山正幸のキマイラ飼育記 このページをアンテナに追加 RSSフィード Twitter

キマイラ・サイトは http://www.chimaira.org/です。
トラックバック/コメントは日付を気にせずにどうぞ。
連絡は hiyama{at}chimaira{dot}org へ。
蒸し返し歓迎!
このブログの更新は、Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama
ところで、アーカイブってけっこう便利ですよ。

2008-11-29 (土)

本日のtip その2:アーカイブにゴミや見せたくないファイルを入れない方法

| 13:48 | 本日のtip その2:アーカイブにゴミや見せたくないファイルを入れない方法を含むブックマーク

ちょっとしたtipでも「ヘーッ」と思う人もいるようなので書いてみます、その2。Unix/Linux/Cygwin/MSYSとかでの話、GNU tarね。

tarは単一のファイルをアーカイブすることもできますが、普通はディレクトリを丸ごとアーカイブするでしょう。アーカイブに入れたくないファイルがあるとき、tarの--exclude=pattern、--exclude-from=file オプションを利用できます。patternはファイル名パターンで、シェルのワイルカード'?', '*'が使えます(ブレイス'{'と'}'は、期待通りには機能しませんから事実上使えません)。

例えば、

$ tar --exclude='*.tmp' -cvf ../archive.tar .

とすれば、*.tmp という名前のフィイルはアーカイブに入りません。--exclude='*.tmp' の代わりに --exclude '*.tmp' でも同じです。でも、--exclude *.tmp とクォートしないとシェルがその場でワイルドカード展開してしまって変なことになります。

--exclude='foo/*.tmp' なら、fooディレクトリの下にあり、名前が*.tmpにマッチするファイルはアーカイブに入りません。fooがディレクトリのとき、--exclude=foo と書くと、foo自身とその下のファイル全てが除外されます。--exclude=.svn が一番使いそうですね。--exclude=foo/ はなぜか効かないので注意してください。

ドットで始まる隠しファイル/ディレクトリを除外するために、--exclude='.*' なんて書くと何もアーカイブされないことになります。--exclude='*/.*' が使えます*1

複数の --excludeオプションを指定することもできます。

$ tar --exclude='*.tmp' --exclude='*/.*'  --exclude=foo \
  -cvf ../archive.tar .

--excludeの除外パターンがたくさんあると、コマンドラインが長くなるので、除外パターンをファイルに書いておくことができます。

*.tmp
*/.*
foo

上の内容のファイルを exclude.list として、次のようにできます。

$ tar --exclude-from=exclude.list -cvf ../archive.tar .

おっと、exclude.list も不要でした*2

$ tar --exclude=exclude.list --exclude-from=exclude.list \
  -cvf ../archive.tar .

*1:ここのパターマッチのメカニズムが、僕はわかってないんですけどね。

*2:exclude.listをexclude.list内に書いておいてもかまいません。

sodasoda 2008/12/01 11:37 eval は邪悪なので、そういう目的で、かつ if を使いたくないなら { ...; } を使う方が良いのではないでしょうか?
[ -z "$1" ] && { echo "Usage: $0 file-or-directory-name"; exit 1; }
セミコロンの必要性が ( ... ) の場合とは異なるので却下かもしれませんが。

m-hiyamam-hiyama 2008/12/01 11:50 sodaさん、
> eval は邪悪なので、
JavaScriptではいつもJSLintに「evalはevilだ」と怒られましたが (http://d.hatena.ne.jp/m-hiyama/20080731/1217493351)、シェルでも邪悪扱いですか?

> セミコロンの必要性が ( ... ) の場合とは異なるので却下かもしれませんが。
またセミコロンの微妙な差ですか、セミコロンもうイヤッ。

sodasoda 2008/12/01 13:05 > シェルでも邪悪扱いですか?

邪悪でしょう。
JavaScript の場合と同様に (CGIなどでは)セキュリティホールの
温床ですし。それに他に代替手段があるのに安易にメタなレベルの
機能に頼ってしまうのはちょっと気が進みません。
まあシェルの場合 eval しか手がないというケースも結構ありますが。

m-hiyamam-hiyama 2008/12/02 10:51 sodaさん、
> 他に代替手段があるのに安易にメタなレベルの機能に頼ってしまうのはちょっと気が進みません。
えっ、そっ、そうですかぁ。

sodasoda 2008/12/09 12:08 > えっ、そっ、そうですかぁ。

う、えっと、そうでもないんでしょうか?
メタレベルとの行き来をするところは、限定/局所化されてないとちょっと気持ちが悪いという感覚があるんですが、これって特殊?

m-hiyamam-hiyama 2008/12/09 13:08 sodaさん、
> これって特殊?
いや、ぼくのほうが特殊かもしれません。evalやapplyがあれば無頓着に使いますからね。