Dokan : Windows版FUSEみたいなもの
面白そうなのがあったのでメモ.
Dokanライブラリは、Windowsのファイルシステムを簡単に書くためのライブラリです。Windows XPとWindows Vistaの32ビット版に対応しています。
http://decas-dev.net/2008/02/05/dokan-library-024-released/
んで,これのRubyバインドもある様子.
そしてこのライブラリの作者自身が作ってるWindows版sshfsのような感じのアプリもいい感じ.
挙動が若干怪しいところもあるけれど,結構いい感じ.
これは使えそうだ.
Dictionary Tooltip の英辞郎を新しいサイトの方にする
http://d.hatena.ne.jp/daftbeats/20070906/1189065163 の再掲載+αです。差分としてはVista,Macの対応と怪しい日本語の修正。
英文を読む機会が多い人にとっては、Firefoxの拡張機能のDictionary Tooltipは便利ですよね。英語のPDFファイルをHTML形式に直したくなるような拡張機能です。
背景
んで、このDictionay Tooltipの和英・英和機能として使われているのが「英辞郎on the WEB」ってやつなんですが、それがURLも変わってイロイロ新しくなりました。
問題
Dictionary Tooltipは、新しい英辞郎には自動的に飛んでくれません。「No definitions found for the selected word」としか表示されません。
原因は英次郎のURL(ホスト)が変わっちゃってるんですね。(http://www2.alc.co.jp/ejr/index.php?word_in=hogehoge → http://eow.alc.co.jp/hogehoge)
解決方法
- エクスプローラーにて、以下のように辿る(WindowsXP限定)
- C(ここは人によって違うかも)
- → Documents and Settings
- → (ユーザー名)
- → Application Data
- → Mozilla
- → Firefox
- → Profiles
- → (ランダムな文字列).default
- → dictionarytip
*注意! Application Dataは隠しファイルになってます。エクスプローラーの設定で隠しファイルを表示するようにしてください。
WindowsVistaの場合は C:\Users\(ユーザ名)\AppData\Roaming\Mozilla\Firefox\Profiles\(ランダムな文字列).default\dictionarytip です。こちらのケースでは AppData が隠しファイルになっています。
Macの場合は。。。
/Users/ユーザ名/Library/Application Support/Firefox/Profiles/2hasy80n.default/dictionarytip/
を編集Winとは少しディレクトリ構成が違うみたいだ。デフォルト設定でも見れてるし。
http://sarusarusarusa.blog119.fc2.com/blog-entry-10.htmlだそうです。なるほど。Macには隠しファイルってのはないのかな。。頭に「.」つけると隠れるとかかな。
dictionarytipフォルダの中のdictionarytip_dictScript.jsをメモ帳なり何なりのテキストエディタで開く。- 578行目辺りにて、
url = " http://www2.alc.co.jp/ejr/index.php?word_in=" + escape(selectedText) + "&word_in2=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a&word_in3=l2zdy6LhJvo58XPPQk";
って書いてあるところの先頭に「//」つけてコメントアウト。んで次の行にコードを書き加える。
//url = " http://www2.alc.co.jp/ejr/index.php?word_in=" + escape(selectedText) + "&word_in2=%e3%81%82%e3%81%84%e3%81%86%e3%81%88%e3%81%8a&word_in3=l2zdy6LhJvo58XPPQk"; url = " http://eow.alc.co.jp/" + escape(selectedText) ;
って感じにする。
- Firefox再起動
- 動作確認する
以上です。
論文がヤバイ
自作ファイルシステムをRedHat系で動かす時注意すべきこと
卒論のために作ってるFuseFSを用いたファイルシステムをFedora8とCentOSで動かしてみようとしました。が、うまくいかなかった。今までの開発はDebianでした。
やはりカーネル(?)の知識無しにファイルシステム構築なんて、どこかしらに弊害が生じますね。
原因がわかったので、メモ代わりに書いておく。
環境
サンプルスクリプト hello.rb を用意します。
require 'fusefs' class HelloDir def contents(path) ['hello.txt'] end def file?(path) path == '/hello.txt' end def read_file(path) "Hello, World!\n" end end hellodir = HelloDir.new FuseFS.set_root( hellodir ) # Mount under a directory given on the command line. FuseFS.mount_under ARGV.shift FuseFS.run
問題点
上記のスクリプトをFedora8,CentOS5で動かし、構築されたhello.txtに対するコマンドの挙動があやしくなります。
まずはDebian4で動かしてみました。このときは特に問題ありません。
$ ls hello.rb mnt $ ruby hello.rb mnt & [1] 1972 $ ls -l mnt 合計 0 -r--r--r-- 1 kui kui 0 2007-12-20 20:16 hello.txt $ cp mnt/hello.txt . $ ls -l 合計 8 -rw-r--r-- 1 kui kui 330 2007-12-20 20:14 hello.rb -r--r--r-- 1 kui kui 14 2007-12-20 20:19 hello.txt dr-xr-xr-x 1 kui kui 4096 2007-12-20 20:16 mnt $ cat Hello, World! $
こんな感じ。
しかしFedora8,CentOS5で同様のことをすると、、、
$ ls hello.rb mnt $ ruby hello.rb mnt & [1] 1972 $ ls -l mnt 合計 0 -r--r--r-- 1 kui kui 0 2007-12-20 20:16 hello.txt $ cp mnt/hello.txt . $ ls -l 合計 8 -rw-r--r-- 1 kui kui 330 2007-12-20 20:14 hello.rb -r--r--r-- 1 kui kui 0 2007-12-20 20:19 hello.txt dr-xr-xr-x 1 kui kui 4096 2007-12-20 20:16 mnt $ cat hello.txt $
となる。
つまり、cp をした時に、RedHatの方は空コピーしかしてくれない。
原因
ファイルシステムとして動いているクラス HelloDir が、hello.txtのファイルサイズを定義していないせいである。どうやら、RedHatな方は、cp をする前にコピー元が空ファイルかどうかチェックするようです。
解法
hello.txtのサイズを与えてあげましょう。
require 'fusefs' class HelloDir def contents(path) ['hello.txt'] end def file?(path) path == '/hello.txt' end def read_file(path) "Hello, World!\n" end # ここから! def size(path) "Hello, World!\n".size # 1 だけでも問題ない end # ここまで! end hellodir = HelloDir.new FuseFS.set_root( hellodir ) # Mount under a directory given on the command line. FuseFS.mount_under ARGV.shift FuseFS.run
コメントにも書きましたが、ようするにマシンに「hello.txt は空じゃない」と認識させればいいため、1 と直接書いてしまっても問題無いです。
FuseFSの実行ユーザ限定アクセスを解除
FuseFSで構築したファイルシステムは初期設定のままだと、スクリプト実行ユーザしかFuseFSファイルシステムにアクセスできない。この制限の解除の仕方をメモ。
FuseFSの初期設定のままの問題点
たとえば。。。サンプルスクリプトの hello.rb だと。
% whoami user1 % pwd /home/user1 % ls -l 合計 8 -rw-r--r-- 1 user1 user1 329 2005-10-11 16:23 hello.rb drwxr-xr-x 2 user1 user1 4096 2007-11-06 23:21 mnt % ruby hello.rb mnt (プロンプト返ってこない)
別端末の別ユーザでログインして、mntにアクセスを試みると。。。
% whoami user2 % cd /home/user1 % ls % ls -l 合計 4 -rw-r--r-- 1 user1 user1 329 2005-10-11 16:23 hello.rb ?--------- ? ? ? ? ? mnt % ls mnt ls: mnt: 許可がありません %
っといった感じ。実はこれは、FuseFSのソースをダウンロードすると、API.txtってのがついてきて、そのAPI.txtの中にこれに関する記述が載っていた。
解法
/etc/fuse.conf を以下の内容で作成する。(初期設定ではこのファイルは作成されない)% cat /etc/fuse.conf user_allow_other %
ソースコードを少し書き換える。hello.rbを編集しましょう。
マウントポイントを指定する部分にて。。。# Mount under a directory given on the command line. FuseFS.mount_under ARGV.shift FuseFS.run
と書いてあるところを。。。
# Mount under a directory given on the command line. FuseFS.mount_under ARGV.shift, 'allow_other' FuseFS.run
これでうまくいっているはずです。動作確認を行ってください
メモメモ
Fuseを一般ユーザ権限で(修正版)
手を出したばかりとは言え、FUSEを一般ユーザ権限での記事はあまりにも酷かった。ココに修正版を記そうと思う。
まずFUSE・FuseFSのインストールに関しては、「FuseFSをyumでインストール」や、「DebianにFUSE・FuseFSを入れるまで」で言及してみた。。。けど、今見返すと前者の記事の内容がカナーリ怪しげ。
また今回FuseFSのスクリプトを動かすのが目的としているが、FUSEを使ったプログラム全般において適応できる内容だと思う。
問題
上記によってFuseFSをインストールした後、一般ユーザ権限でさっそくFuseFSのサンプルを使おうすると。。。
$ sudo modprobe fuse # fuseモジュールを有効に $ ruby hello.rb mnt fuse: failed to exec fusermount: Permission denied /usr/lib/ruby/site_ruby/1.8/fusefs.rb:13:in `for_fd': no implicit conversion from nil to integer (TypeError) from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:13:in `run' from hello.rb:20
となる。
当然だがroot権限で実行する分にはこの問題は起きない。
解法
自分なりの注釈を加えつつ順に記述していく。
目的としては、ユーザ「hoge」がFuseFSのサンプル「hello.rb」を実行できることが目標。
まず現在のスタート時の環境を示しておく。# whoami root # uname -a Linux debian 2.6.18-5-686 #1 SMP Wed Oct 3 00:12:50 UTC 2007 i686 GNU/Linux #
また、上のサンプルはroot権限で実行する限りでは問題無く動作する環境。
グループfuseに、ユーザを追加する。# adduser hoge fuse
これで、/usr/bin/fusermountと、/dev/fuseへのアクセス権限を手に入れたことになる。
/usr/bin/fusermountと、/dev/fuseのパーミッションを確認します。# ls -l /usr/bin/fusermount -rwsr-x--- 1 root fuse 18368 2007-03-11 22:22 /usr/bin/fusermount # ls -l /dev/fuse crw-rw---- 1 root fuse 10, 229 2007-12-02 11:29 /dev/fuse #
違っていたら。。。
動作テスト。サンプルのhello.rbを動かしてみませう。# mkdir mnt # ruby /usr/share/doc/libfusefs-ruby1.8/example/hello.rb mnt & # ls mnt hello.txt # cat mnt/hello.txt Hello,World! # fg [1] + 1984 runnning ruby /usr/share/doc/libfusefs-ruby1.8/example/hello.rb mnt (Ctrl+Cで終了。なにやらメッセージが返ってくるけど問題無い。) #
Debian4.0の人向けオマケ。
fuseを使うたびにイチイチ# modprobe fuse
ってやるのが面倒な人は、/etc/modulesって設定ファイルの末尾に「fuse」と入力し、改行し、ファイルを保存してみてください。これで次回システム起動時に「/etc/init.d/module-init-tools」と言うスクリプトがmodprobeしてくれます。
次書くのは、FuseFSのスクリプトでマウントしたディレクトリに、スクリプト実行者以外のユーザがアクセスする方法について書けたらいいなと思う。
VMware起動時に「致命的なアプリケーション エラーです:・・・」
新たなマシンにVMWareを入れる機械があったのですが、仮想マシンを立ち上げるたびに、
致命的なアプリケーション エラーです: 文字列のエンコード中にエラーが発生しました。(class cui::Error)。
なんて出て来て、かつググってもこのケースに適切な解法がなかったので書き書き。
真っ先に気がつくべき事実に気がつかず、無駄に苦労してしまった。。。(計12時間)
また、この記事を書いた時点では、「致命的なアプリケーション エラーです: 文字列のエンコード中にエラーが発生しました。(class cui::Error)。」に関してググっても、2007年10月に修正されたバグの話しか見当たらなかったため、この記事を書いてみた。
問題点
仮想マシンを立ち上げて少しすると、「致命的なアプリケーション エラーです: 文字列のエンコード中にエラーが発生しました。(class cui::Error)。」とエラーウィンドウが出力され、[ OK ]ボタンを押すとVMwareが仮想マシンとともに強制終了される。
(このときVMwareのプロセス(タスク?)が残っているので、タスクマネージャで強制的に終了しておいたほうがいいかもしれない。)
(また、このエラーウィンド、自分のケースでは無視していても仮想マシンは正常に動いていた。なのでエラーウィンドが気にならない人は以下を読まないくてもいいかもしれない。)
解法
問題のxmvファイルと同じフォルダに移動。.log のファイルがあるはずなので、テキストエディタで開きましょう。一通り目を通すと、どこかに文字化けしている箇所があるはずです。僕のケースでは、、
Dec 09 22:28:56.435: vcpu-0| BUSLOGIC: Store HAL[18] = 0xfe01 Dec 09 22:28:57.433: vmx| VMXVmdbLoadUsbDevices: New set of 2 USB devices Dec 09 22:28:57.433: vmx| USB: Found device [name:USBデバイス147e:2016 vid:147e pid:2016 path:1/0/0 speed:full family:vendor] Dec 09 22:28:57.433: vmx| USB: Found device [name:Ricoh\ USB繝・ヰ繧、繧ケ vid:05ca pid:183a path:1/2/1 speed:high family:other] Dec 09 22:29:01.007: vcpu-0| BUSLOGIC: Store HAL[16] = 0xffff Dec 09 22:29:01.007: vcpu-0| BUSLOGIC: Store HAL[18] = 0xfe01 Dec 09 22:29:01.007: vcpu-0| BUSLOGIC: Store HAL[16] = 0xffff
こんな感じ。
USBデバイスが二つ認識されたは良いけど、一方が文字化けしてしまっています。なので、vmxファイルを弄ってUSBデバイスを読み込まないように変更します。このケースでは、vmxファイルの一部は。。。
ethernet0.connectionType = "nat" usb.present = "TRUE" sound.present = "TRUE"
となっていたので、usb.presentの値を書き換えます
ethernet0.connectionType = "nat" usb.present = "FALSE" sound.present = "TRUE"
これで解決。
つまり、「致命的なアプリケーション エラーです: 文字列のエンコード中にエラーが発生しました。(class cui::Error)。」とでてきたら、ログファイルを見ろということ。。。。当然な話にまとまってしまう。