FuseFSを使ってみた

学祭があったためFuseFSを使えるようにしてから弄るまで間が空いてしまった。しかし、3日目最終日に雨が降り暇を持て余したのでFuseFSを弄ってみた。
ファイルシステムの構築なんてしたことないから恐る恐るでしたが、意外と簡単にできました。FuseFSの力ですね。

サンプルスクリプトを動かしてみる。

どうユウ風に作るかは、fusefs-0.6.0.tar.gz同梱のAPI.txtやら、sampleディレクトリ以下にあるサンプルスクリプトに説明を任せるとして、、、
困ったのが、サンプルスクリプトの動かし方がよう分らんのです。
sampleディレクトリに入っているスクリプトの内とりあえずソースを読み、四苦八苦しつつ実際に動かしてみたのは、

  • hello.rb
  • demo.rb
  • yamlfs.rb
  • openurifs.rb

です。
他のスクリプトは、他の環境も必要っぽかったので保留。


はじめにマウントするためのディレクトリを用意する。

% pwd
/...../fusefs-0.6.0/sample
% mkdir mnt
% ls
demo.rb  dictfs.rb  hello.rb  hoge  mnt  openurifs.rb  railsfs.rb  sqlfs.rb  yamlfs.rb

スクリプトを一通り動かしてみる。

hello.rb

% ruby hello.rb mnt & #スクリプトの実行とmntにマウントする.「&」忘れずに
[1] 8115
% ls mnt
hello.txt
% cat mnt/hello.txt 
Hello, World!
% kill -s INT 8115 #スクリプトの停止とアンマウントをしている
/usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `select': Interrupt
        from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `run'
        from hello.rb:20

[1]  + 8115 exit 1     ruby hello.rb mnt2
% ls mnt #アンマウントができているか確認している
%

demo.rb

これは面白かった。

% ruby demo.rb mnt &
[1] 8185
% ls mnt
animal  color  counter  hello  progress  (あなたのアカウント名と同名のディレクトリ)
%
% cat mnt/progress
.......  
% #(少し時間おいてから)
% cat mnt/progress
........... #(時間が経つと5秒ごとに「.」が増える。最大20個?)
%
% cat mnt/animal
duck #(ファイルの内容が複数ある内から乱数で選ばれる。colorも同じ)
% cat mnt/animal
dog 
%
% cat mnt/counter
1 #(読み込まれるたびにカウントアップ)
% cat mnt/counter
2
% cat mnt/counter
3
% kill -s INT 8185
/usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `select': Interrupt
        from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `run'
        from demo.rb:93

[1]  + 8185 exit 1     ruby demo.rb mnt2
%

yamlfs.rb

これは、ファイルシステムを内部ではハッシュとして扱っている。つまり、キーがファイル名、値がファイル本体、となっている。値が文字列ならばファイル、値がハッシュならばディレクトリと扱っている。ファイルシステムの全体をyaml形式で逐次保存している。

% ruby yamlfs.rb mnt test.yaml & #第二引数はファイルシステムを保存するためのyamlファイルの名前。存在しなくても構わない。
[1] 8263
% ls mnt #はじめは空
% echo hogehoge > mnt/hoge #ファイル名hoge、内容hogehogeのファイルを作る
% ls mnt
hoge
% cat mnt/hoge
hogehoge
% ls test.yaml #yamlfs上でファイル・ディレクトリ操作をするたびに、test.yamlにハッシュの内容が出力される 
test.yaml
% mkdir mnt/foo
% ls mnt
foo  hoge
% cat test.yaml
---
hoge: |
  hogehoge

foo: {}

% kill -s INT 8263
/usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `select': Interrupt
        from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `run'
        from yamlfs.rb:162

[1]  + 8263 exit 1     ruby yamlfs.rb mnt2 test.yaml
% ruby yamlfs.rb mnt test.yaml &
[1] 8310
% ls mnt
foo  hoge
% kill -s INT 8310
/usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `select': Interrupt
        from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `run'
        from yamlfs.rb:162

[1]  + 8310 exit 1     ruby yamlfs.rb mnt2 test.yaml

openurifs.rb

これはopenuriをrequireして、リモートのファイルを取得することが可能になる。

% ruby openurifs.rb mnt &
[1] 8330
% ls mnt # なにもないように見えるけど。。。
% head mnt/http/www.ruby-lang.org/ja/index.html #mnt以下にURLっぽいのを入れると。。。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>オブジェクト指向スクリプト言語 Ruby</title>
    <link rel="stylesheet" type="text/css" href="/stylesheets/low.css" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/screen.css" media="screen" />
    <link rel="stylesheet" type="text/css" href="/stylesheets/print.css" media="print" />
    <link title="Low vision" rel="alternate stylesheet" type="text/css" href="/stylesheets/low_vision_screen.css" media="screen" />
    <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico" />
% kill -s INT 8330
/usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `select': Interrupt
        from /usr/lib/ruby/site_ruby/1.8/fusefs.rb:15:in `run'
        from openurifs.rb:52

[1]  + 8330 exit 1     ruby openurifs.rb mnt2

「mnt/http/www.ruby...」てのは表記ミスではありません。。。内部でmnt以下のパスを「/」でスプリットしてURLの形にしています。

自分でも作ってみた

yamlfs.rbのソースコードが気に入らなかったので、練習の意味を兼ねてyamlfsのマネをしてみた。ただ、時間の関係上yaml形式でファイルシステムを外部に保存する機能は省く。つまり、アンマウントされたら無くなってしまう、揮発性ファイルシステム。。。

特に書くことなく、うまくいきました。

API.txtに載ってるけどサンプルコードで使われてないクラス

MetaDirというクラス。
ファイルシステムを抽象化したクラスを、一つのディレクトリに手軽にたくさんマウントできるようになるクラス。なんだけど。。。あんまりうまく使えない。
例えば、、、

  • MetaDirの下にある置かれたファイルシステムオブジェトAがあるとする
  • Aはメソッドを一通りキチンと定義されている。

と、このような状況下においてこちらの意図しない挙動が発生する。

  • Aのメソッドexetutable?と、メソッドtouchが呼ばれない。

なんででしょ?
MetaDirかぁ無くても構わないから放っておこうかな?