Install shared-mime-info on OS X Yosemite

任意のファイルの種類が何であるかを特定したいとき、その拡張子で判断してしまうようなお人好しでない限り、話はそう簡単ではありません。

簡単ではないので理由は端折りますが、実装するには Perl ではモジュール File-MimeInfo を用いるところへ落ち着くと思われます。 Ruby だと mimemagic かしら。

しかしそれらが有効に働くには、 shared-mime-info というパッケージが、そこに入っていなければなりません(追記: mimemagic では不要でした。 gem のライブラリに Magic データを持っていました)。それは何かというと──冒頭の一文を引用します:

The shared-mime-info package contains the core database of common types and the update-mime-database command used to extend it.

つまり、ファイルの種類のデータベースですね。

ところで、じぶんの環境は OS X (Yosemite) であります。先に言って仕舞えば、ここには shared-mime-info はありません。したがって、たとえば Perl のそのモジュールをインストールして、こんなふうに実行したところで、むなしい結果を得ることとなります(なりました)。

1
2
3
4
5
$ perl -MFile::MimeInfo -E 'say mimetype(shift)' ~/Desktop/IMG_4494.PNG 
WARNING: You don't seem to have a mime-info database. The
shared-mime-info package is available from http://freedesktop.org/ .
application/octet-stream
$ 

打ち明けると、逆にこのことから、ああ shared-mime-info というのが別途必要なんだなということに気づいたのですけれども、さて、ではインストールしよう、となるのは自然な成り行きになるのですが、しかしこれが結構ハマってしまったので、こうしてメモして残そうと思うに至った次第です。

しかしお断りですが、それは局所的・限定的なプロブレムに対する対処療法の一種で、前向きに捉えればある意味「旬」なものではありますが、おそらくほとんどのひとには役に立つものではありませんし、じぶんの環境ですら腐りやすい、そういう内容になっていますので、どうか悪しからず。

──その手順は、試行錯誤してインストールに成功した時までの走り書きメモをまとめて、バッチ・スクリプトにして、 Gist に置きました。スクリプトと言うと偉そうですが、見ると分かるとおり、チェックとか、エラー処理とかまったくしていないので、これをそのまま使うのはどうかと思います。ので、見るだけにして実行はしないでください。

install-shared-mime-info.sh

ハマリ・ポイント( hummerly point … )は、本丸 shared-mime-info のビルドです。

configure 自体は成功裏に終わったので、では続いて make とするのですがこんなエラーに遭遇しました。要約すると、コマンド xgettext がないぜ、と言われています:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ PKG_CONFIG=$PREFIX/bin/pkg-config PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig ./configure --prefix=$PREFIX
$ make
  GEN      create-pot
INTLTOOL_EXTRACT="$PREFIX/bin/intltool-extract" XGETTEXT=":" srcdir=. $PREFIX/bin/intltool-update --gettext-package shared-mime-info --pot
Can't exec ":": No such file or directory at $PREFIX/bin/intltool-update line 713.
Use of uninitialized value $version in pattern match (m//) at $PREFIX/bin/intltool-update line 714.
 *** GNU xgettext is not found on this system!
 *** Without it, intltool-update can not extract strings.
...
...
make[1]: *** [check] Error 1
make: *** [check-recursive] Error 1
$ 

このメッセージから直接は読み取れませんが、 intltool をインストールした際に入ったコマンド intltool-update が Perl スクリプトなのでその中を見ることができたのでそれ見てみると、 intltool-update を実行する際に xgettext の情報を正しく渡していない Makefile が悪いとわかります。そして Makefile が悪いなら、それを生成する configure に問題がある、と捜査の手は進みます。

記憶を過去に辿ってみれば、 configure を実行したときには、コマンド xgettext が見つかっている旨が表示されているのですが(実際 PATH も通っています)、しかし現実として生成された Makefile の中では、(それが見つかっていなかったときの意味だろうと思うのですが、) : という何もしないコマンドとして記録されていました。従って、 intltool-update はそれを xgettext とみなして実行したので、 Can't exec ":": No such file or directory というエラーメッセージになり、なるほど辻褄が合うようです。──合ったところで、解決には繋がっていませんが、ちょっと気持ちがすっきりしました。

結局どうしたかというと、 intltool-update を手動で実行しました。これが、どういうことなのかは知りませんが、とりあえずインストールするのが目的になっているので、知らないまま先に進めます。

具体的には、実行されてエラーになったコマンドラインから XGETTEXT=":" のところを削ってしまえば、コマンド・サーチ・パスにある xgettext コマンドが intltool-update 内部から使われる手筈になっていましたので、そうしました。ちなみに、その場で実行したら po ディレクトリに移ってやりなさいという親切なメッセージが出てきたので、それに従い。そして、 make の続きをやり直します。

1
2
3
4
5
$ cd po
$ INTLTOOL_EXTRACT="$PREFIX/bin/intltool-extract" srcdir=. $PREFIX/bin/intltool-update --gettext-package shared-mime-info --pot
$ cd ..
$ make
$ make install

望むらくば configure スクリプトを見直したりするべきなのかもしれませんが、それを追求するのはまた別の話になります。今回はただ、ファイルの種類を特定したいのが目的であるのですから、ツールのビルドの問題に対しては、これで十分のような気がします。尤も、その手腕を持たないじぶんの言い訳なのではありますが、次に示すように、望むべく結果を得ることができたのですから、その場しのぎにしては良い案配ではないでしょうか:

1
2
3
$ XDG_DATA_DIRS=$PREFIX/share perl -mFile::MimeInfo::Magic=magic -E 'say magic(shift)' ~/Desktop/IMG_4494.PNG
image/png
$ 

以上のように、じぶんの場合、任意のファイルの種類が何であるかを特定したいとき、話はそう簡単なことではなかった、という話でした。