.NET Assembly を mono と関連付ける
Linux 上でも mono を使うと .NET Framework を動作させることが出来ます。Linux 環境で mono をインストールする方法は 以前の記事 に書きましたが、このままでは .NET のプログラム(.NET Assenbly)を実行する都度、以下のように mono を実行する必要があります。
1 2 |
|
binfmt_misc という仕組みを使うと、毎回、"mono" としてしなくても、あたかも ELF と同等に .NET Assembly を実行出来るようになります。余談ですが、binfmt_misc の公式ページ は 404 not found になっているようです。
テスト用プログラム¶
今回は CentOS 5.5 x86_64 環境で検証を行ないました。また、今回用意したテスト用プログラム "hello.cs" は以下の通りです。
1 2 3 4 5 6 7 8 9 |
|
予め、このプログラムをコンパイルしておきます。
1 2 3 |
|
file コマンドのバージョンアップ¶
今回の環境にインストールされていた file コマンド(バージョン 4.17)で .NET Assembly を確認すると、以下のように表示されました。
1 2 3 4 5 |
|
必須ではありませんが、file コマンドのバージョンを上げると、明示的に ".NET Assembly である" ことが表示されるようになります。file コマンドのソースコードをダウンロードし、コンパイル&インストールします。現時点での最新版はバージョン 5.04 でした。
1 2 3 4 5 6 |
|
インストールが完了したことを確認します。
1 2 3 4 5 |
|
新しいバージョンの file コマンドだと、.NET Assembly であると明示的に表示されていることが分かります。
1 2 |
|
binfmt_misc で .NET Assembly と mono を関連付ける¶
mono を関連付けていない状態でシェル上から直接、.NET Assembly を実行すると、下記のようなエラーになります。
1 2 |
|
mono の公式ページにあるドキュメント「Guide:Running Mono Applications」には以下のような記載があります。
1 |
|
しかし、Novell で公開されている RHEL 向けのパッケージは /opt 配下にインストールされる為、一見すると下記のように書き換えるのが正しいように思えますが、これでは正しく動作しません。
1 |
|
実際に試してみると、下記のようなエラーになります。余談ですが、上記コマンドの先頭(つまり、echo の前)に sudo を付与しても、リダイレクト先が元のユーザ権限で動作しますので、/proc 配下へ書き込むことが出来ません。こういった場合は下記のように、echo コマンドの結果をパイプし、sudo して root 権限を付与した tee コマンドへ渡してやります。
1 2 3 |
|
エラーの原因ですが「"mono" はシェルスクリプトである」ことが原因のようです。このスクリプトの内容は以下のようになっており、実際には ELF である mono.bin が呼ばれているようです。
1 2 3 4 5 6 7 8 9 |
|
binfmt_misc の設定を変更し、"mono" ではなく、"mono.bin" を呼び出すようにします。先程、作成した設定は "echo -1" してやることで削除することが出来ます。
1 2 |
|
これでいちいち mono コマンドを指定しなくても、シェルから直接、.NET Assembly を実行出来るようになりました。
1 2 |
|
binfmt_misc のメカニズム¶
ソースコードを読んだわけでは無いのですが、binfmt_misc のメカニズムを動作結果から推測して記載しておきます。 Linux ネイティブの "ELF" 形式 のファイルで Hex ダンプを取得すると、以下のように冒頭部分は「.ELF」になっていることが分かります。
1 2 |
|
この冒頭部分のことを「マジック・ナンバー」と呼びます。同様に .NET Assembly に対して Hex ダンプを取得するとマジック・ナンバーは "MZ" で始まっていることが分かります。
1 2 |
|
binfmt_misc は、このマジック・ナンバーを見分けて、実行するプログラムを変更出来る仕組みのようです。今回の環境では特に何もしなくてもデフォルトで binfmt_misc が有効になっているようで、mount コマンドを実行すると binfmt_misc が /proc/sys/fs/binfmt_misc にマウントされていることが分かります。
1 2 3 4 5 6 7 8 9 |
|
/proc/sys/fs/binfmt_misc/register へ設定を書き込むことで、binfmt_misc に新たなマジック・ナンバーを登録することが出来ます。以下の通り、register は WriteOnly になっています。
1 2 3 4 |
|
前述した通り、echo コマンドを使って register へ設定を書き込みます。echo している文字列ですが、"CLR" の部分は設定自体に割り当てる任意の名前、"MZ" 部分はマジック・ナンバー、"/opt/ 〜" 部分は実際に起動されるプログラム(これを「interpreter」と呼ぶようです)を意味しているようです。register へ echo した設定は /proc/sys/fs/binfmt_misc 配下に保存されますから、これらを cat 等で閲覧することで設定を確認することが可能です。
1 2 3 4 5 6 7 |
|