2009-02-01 [長年日記]
_ php -c で ini ファイルを指定するとデフォルトのものは読み込まれない
例によって twitter ログからサルベージ。ネタが混んでいたので1月29日のネタを2月1日分として書く。
11:10:39 >wtnabe< また ini_get( 'include_path' ) で取れる値が予想しない
ものになって苦しんでいる。なんでぢゃっ。
11:21:57 >wtnabe< どっから出てくるんだろう、この値は
11:25:35 >wtnabe< php -c で ini ファイルを指定する場合、システムデフォ
ルトの php.ini は読まないのか。その中に include_path が書かれ
ていない場合は恐らくコンパイル時に決定する include_path が出て
きてしまうと。
11:26:35 >wtnabe< ということはスクリプトの動作時に include_path にパス
を追加しようにも基準のパスが狂っていてどうにもならない場合があ
ると。
何をしようとしていたかというと、include_path を補正してコマンドラインからテストを動かすための ini ファイルを生成して、それを食わせてテストを動かすということをよくやるのですが、思わぬ値が返ってきて混乱していたのでした。
今にして思うと -c で読み込むべき ini ファイルを指定しているのに、指定していないファイルを読み込んでしまうとしたらそれは明らかにおかしい。当たり前っちゃ当たり前なんだけど、値が空になるのではなく予想外な値が出てきたところで混乱したらしい。
ちなみに help ではこんな感じに書かれている。
$ php --help Usage: php [options] [-f] <file> [--] [args...] ... -c <path>|<file> Look for php.ini file in this directory -n No php.ini file will be used -d foo[=bar] Define INI entry foo with value 'bar'
あ、ini ファイル名だけでなくディレクトリ名でもイケるのか。
※ おまけで。このときは Linux 上で作業していたのですが、カレントディレクトリの php.ini ファイルがどうしても読み込まれてしまうようなので php.my.ini という名前のファイルを生成するようにしました。でも今、手元の OSX では再現しません。なんなんだろう。マニュアルを読むとカレントディレクトリの方を後で探しに行くはずなので、勝手に読まれることはなさそうなんですけどね…。
2009-02-03 [長年日記]
_ 豆電球を LED のものに変えた
先日、豆電球を買いに電気屋に行ったが、
- グロー管
- ナツメ球
- 常夜灯
というものはあるが豆電球という製品が置いてなかった。混乱してスゴスゴと逃げ帰ってきた。
その後調べて今度はしっかり LED の常夜灯を買ってきた。多少単価はあがるが、つけっぱなしなので寿命が長くて消費電力の小さいもの*1の方がそりゃよかろうという判断。
ナツメと比較すると LED の方がちょっとギラツキ感はあるが、部屋そのものの明るさはナツメの方がちょっと明るかった。微妙な違いではあったが、ナツメの豆電球ってちょっと明るすぎない?と感じている人にはちょうどいいんだと思う。逆に言うとナツメの明るさに慣れて、ある程度の作業があの明るさの下でできるようになっていたような人だとちょっと最初は暗すぎると感じるかもしれない。
*1 ナツメ5W -> LED 0.2W
2009-02-06 [長年日記]
_ Net::SSH で明示的に password 認証に
twitter log 掘り起こし日記。
12:55:10 wtnabe< デフォルトと違う設定の ssh で capistrano を使おうとし て大ハマり中 13:19:15 wtnabe< なんか :auth_methods の扱いもおかしいっぽいなぁ 13:20:57 wtnabe< passphrase を聞いてくるのが謎い 13:22:25 wtnabe< 自分自身の passphrase を使うわけではないので :auth_methods を password に限定すると認証に失敗する 14:32:21 wtnabe< :ssh_options[:keys] = [] にしたら passphrase 聞いてこ なくなった
Net::SSH 単体ではなく Capistrano で使っていたんだけど、
set :ssh_options[:keys], []
にしたってことです。
何のことかと言うと、自分の環境で ssh connection 絡みのテストをやると自動的に自分の config が反映されて面倒なことになっちゃったりするので、その辺をリセットするために行った措置だったりします。
※ 関係は薄いのですが password を Capfile の外から与えられないとまずいよなぁと思ったのと、どの程度のできるのか確かめたくて CLI.ui も試してみました。これは
highline というライブラリを使っているわけですが、こいつが、なのか Capistrano の CLI の使い方が、なのか readline が効かない状態。対話的な処理を真面目に作り込もうとするとちょっとキツいかもしれません。
cap shell
は readline 効いてるのにね。
2009-02-09 [長年日記]
_ Capistrano と Rake の比較
実は最初 Capistrano の記事を書いたときは大真面目に一部 Rake の機能を使っていると思っていた。コードも読んでなかったし、task 定義の構文が似ているというだけでそう思い込んでしまった。
でも実は全然ベツモノだったことにあとで気づいた。とは言え似ているのは実際に似ているので、自分の気づいた似ている点、同じように使える点、違っている点をちょっと挙げてみようと思う。
あくまで task 定義、実行時に使えるところの話で、中身の違いについてはほとんど言及していないのであしからず。
似ている点
- task do; end によるタスク定義
- まぁこれが基本ですね
- namespace do; end による namespace 定義
- コマンドラインオプションもよく似ている
異なる点
コマンド名、デフォルトの定義ファイル名が違う
| ツール | コマンド | デフォルトの定義ファイル名 |
| Rake | rake | Rakefile |
| Capistrano | cap | Capfile |
default/file/directory task がない
実は自分は Rake をビルドツールとして使っていないためか、この default task の動作はイマイチ馴染めずにいた。Capistrano はこれがなくなっただけですっきりした感じで、好感を持ったりしている。
依存タスクの定義方法
rake では
task TASK => depends do ... end
という形で depends の位置に依存 task を書くことができ、file task, directory task ではこの機能を使うことで関係するファイル群を簡潔に記述することができる。しかし Capistrano ではこういった書き方はできない*1。Capistrano では以下のように依存 task ではなく、trigger に別の task を登録していく形になっている。
task :taskA do ... end task :taskB do ... end before :taskA, :taskB
before だけでなくいろいろ trigger があり、これらの trigger 用のメソッドに task を追加していく。最初ちょっと面倒だなと思ったが、これはこれで読みやすく、すぐに慣れることができた。
接続先サーバの記述
Rake で依存タスクを書く位置には接続先のサーバ群を記述することができるようになっている。
task :taskA, :roles => :ROLENAME do ... end
という形で記述する。:roles に書ける role は
role :ROLENAME, hostname1, hostname2, ...
という形で定義しておく。
task の呼び出し
Rake の場合は他の task の呼び出しは depends に書く以外に方法がない。しかし Capistrano では他の task をメソッドと同じように呼ぶことができる。
まぁ凝った処理をする場合は task ではなく独自に module や class を定義していくことになっていくだろうから、この機能はあまり使わないと思うけど。
スコープ
Rake の場合は「地の文」も namespace も task も Global なというか main のメソッドなので、例えばそこで定義した変数は main に属しており、それが分かっていれば値のやりとりはそれほど大きな苦労がない。
しかし Capistrano の場合は Rake で main に当たる部分が Capistrano::Configuration となり、namespace も task もすべて別々の階層に属すオブジェクトとなっている。*2そこで Capistrano では set というメソッドを使って独自に変数を定義し、fecth でその値を取り出すことで、task 間で変数をやり取りできるようにしている。
set :var, val
fetch :var
Capistrano を Rake のように使う
以下の点に気をつければ Capistrano と Rake の違いをあまり気にせず使える。気をつけてほしいのは、Capistrano があれば Rake なんて要らないぜ!ということを言いたいわけではないということ。あくまで、この場合は Rake、この場合は Capistrano、と使い分けを考えなくても、この辺だけ意識すれば Capistrano だけでもある程度イケるよ、ということで書いている。
接続先サーバを記述しない
task :TASKNAME, :roles => :ROLE do ... end
ではなく
task :TASKNAME do ... end
で書いていく。
run メソッドを使わない
run メソッドはリモートのサーバにログインして実行するためのものなので、
task :TASKNAME do system() end
あるいは
task :TASKNAME do Rubyコード end
だけで書くようにすればリモートサーバへのログインなしに task を実行できる。
_ 一発採血
健康診断だった。例年採血で手こずるのだが、今年はそのことを告げたら最終兵器、卓上ヒーターが出てきた。これで手を温めてから採血に望んだら一発で採れたよ!
ちなむと、毎年健康診断はこの時期の朝イチに行っているので、
- 寒い
- 起き抜けで血が巡っていない
- おまけに朝ご飯も食べていない
という状態で、末端冷え性の自分はまずまともに採血できないのであった。一発で採れるなんてすごい快挙。
2009-02-10 [長年日記]
_ Ruby で expect してみた
ちなみにオリジナルの expect は使ったことがなく、以下の解釈が正しいかどうかはまったく分からないのであしからず。
気をつけることは、
- とにかく一定の順番を見つけること
以下、ハマったところ。
- パターンにマッチしない場合を考えて timeout をセットしないと永遠に終わらない可能性アリ
- パターンにマッチしなかった場合は nil しか得られないので、何の処理に失敗したのかは判別不能
- 正規表現マッチをあまり厳密にしたらまずい?
全部苦労したけど 3 は今でもなんかすっきりする答えを見つけられないでいる。上のコードで prompt を見つける正規表現に $ があったりなかったりするのはそれが理由。基本的には $ まで書いてキッチリ表現したいんだけど、つけるとなぜかマッチしなくなったりして、意味がよく分からないのであまり絞りすぎないことにした。でもそうすると予期しないところにマッチしそうで気持ちよくない。
なんでこんなことしてたかというと、sudo の使えないサーバで root 権限でコマンドを実行したかったから。ほんとは Capistrano で片付くと思っていたけど sudo が使えないということで急遽 expect のお出ましとなった。やってみると実際には expect だけで解決するわけでもなく、なかなか苦労の大きな作業になってしまった。
でもまぁ expect が使えれば自動化できる処理はけっこう増えるわけで、タイミング的にはちょっとつらかったが必要に迫られたおかげでまた一つ幅が広がったと喜んでおくことにした。
cf.
2009-02-11 [長年日記]
_ VBox アップグレード時は設定のバックアップを確認
これたぶんどのバージョン間でもちゃんと ChangeLog 読んで確認した方がいい。
というのもバージョンアップ時に設定用の XML ファイルの形式が変わることがあるんだけど、これの自動変換がたまにミスるっぽい。具体的には VBox 2.1.2 に上げたときにゲストを起動できないことが Windows ホストでも Mac ホストでも、ゲスト OS の種類を問わずに発現したんだけど、設定ファイルを開いて VBoxManage setextradata を使って追加した NAT の設定を外したら起動したというもの。
VirtualBox はまだ比較的マイナーというかあまり声高にレポートを書いている人が多くない印象で、この辺のノウハウが出回っているのをあまり見ない。
とりあえず困ったらデフォルトの設定ならたぶん起きるよ
と、未来の自分のために書いておく。
ちなみに、形式が変更になる場合は実は migration の過程で自動バックアップが走る。んだけど、何をバックアップしておきたいかは自分で決めておいた方がいいような気がする。
2009-02-12 [長年日記]
_ VirtualBox のディスクを増量…できなかった
とある VirtualBox 上の CentOS のディスク容量が足りなくなってきたので増やそうと思った。
……。
!
おおーっと。できないでやんの。マジか。
それだけだとあんまりなので分かったことを。
LVM が絡むと面倒なのかも
VirtualBox の GUI にはディスクを大きくする方法はなかったので、HDD にインストールしていない knoppix か何かで起動し、partition サイズを変更しようとした。しかし CentOS はデフォルトで LVM にインストールされ、これのサイズを自由に変更できるツールはないっぽかった。少なくとも GPart や QTParted では不可能だった。仕方なく、
- VirtualBox で新しく、より大きめのディスクを作成
- (別なシステムで立ち上げ)
- dd で手狭になったディスクの内容をコピー
- そのままではサイズが変わらないので、pvresize, vgresize, lvresize で大きくなったディスクに合わせて LVM のサイズを目一杯大きくした
中の CentOS は kernel panic で立ち上がらなくなった orz (snapshot を撮っておいたのでちゃんと元に戻せたよ。)
qemu-img はまだ vdi には対応していない
もしかしてディスクフォーマットを変換したらサイズ変更するツールあるかも、と思って変換を試みたが、QEMU に入っている qemu-img では vdi は扱えなかった。
VirtualBox 2.1.0 から vdi 以外にも対応
実は VirtualBox は 2.1.0 から VirtualBox 独自である vdi 以外の仮想ディスクフォーマットも使える。
- Full VMDK/VHD support including snapshots (see user manual, chapter 5.2, Disk image files (VDI, VMDK, VHD), page 72)
またマニュアルにもほとんど記載がないが
VBoxManage internalcommands
というサブコマンドのサブコマンドでディスク形式の変換ができるようになっている。
$ VBoxManage internalcommands converthd
VirtualBox Command Line Management Interface Version 2.1.2
(C) 2005-2009 Sun Microsystems, Inc.
All rights reserved.
Usage: VBoxManage internalcommands <command> [command arguments]
Commands:
converthd [-srcformat VDI|VMDK|VHD|RAW]
[-dstformat VDI|VMDK|VHD|RAW]
<inputfile> <outputfile>
converts hard disk images between formats
ということは VMWare があれば容量の変更はできるのかなーという感じもしている。でもそれって VirtualBox の存在自体否定しちゃってるし、実際持っていないので試せていない。
cf.
Fly together Forever » Convert VirtualBox image (vdi) to VMWare (vmdk)
2009-02-14 [長年日記]
_ git独自制限shellなんてものがあるのか
何の気なしに
$ git-<TAB>
と補完させてみたところ、
git-cvsserver git-shell git-upload-pack git-receive-pack git-upload-archive
と出てきたので git-shell ってなに?と思ったら
$ man git-shell
NAME
git-shell - Restricted login shell for GIT-only SSH access
mjd.
そうか、そうなると ssh 越しの git を使わせるのはずいぶん楽になるんだね。何しろ git そのものが制限 shell を提供してくれるんだから。
なるほどなぁ。
_ Rubyで変数から定数を得る
はいはい。例によって twitter のログです。
20:57:16 wtnabe< Ruby で変数の中身を定数として参照して #{var}.new みた
いなことってできないよね。eval しか方法ないのかな。
(この間、ご飯を食べる)
21:11:01 finalfusion> @wtnabe 変数がクラス名を抱えていて、そこからイン
スタンスをつくりたい?
21:20:02 m_seki> @wtnabe const_get('ClassName') ?
21:29:40 wtnabe< @m_seki おぉ。できました! ありがとうございます!
const_get() ってそういう意味だったんですね。
21:30:53 wtnabe< @finalfusion ですです。疑問を twitter に投げてご飯を食
べてたら解決しましたw
21:47:01 finalfusion> @wtnabe const_get 書こうとしたらすでに @m_seki さ
んがががw
なるほど。
こんな風に使います。
def namespaces
return %w(dotfiles firefox)
end
namespaces.each { |n|
namespace n do
utils = Object.const_get( n.capitalize ).instance
なるほどなぁ。なんとなく String#to_const みたいなメソッドがあるのかと思ってたんだけど、そういうんじゃないのね。
2009-02-18 [長年日記]
_ .gitignore は .cvsignore と違ってホームディレクトリのものはデフォルトでは解釈されない
info cvs より
C.5 Ignoring files via cvsignore
================================
(snip
* The per-user list in `.cvsignore' in your home directory is
appended to the list, if it exists.
man gitignore より
NAME
gitignore - Specifies intentionally untracked files to ignore
(snip
o Patterns read from the file specified by the configuration variable
core.excludesfile.
git の場合、~/.gitconfig は解釈されるが、この中で
[core] excludesfile = /path/to/.gitignore
の形で ~/.gitignore を指定してあげてないとその中身を ignore 対象にはしてくれない。おまけにちゃんとフルパスで書いてあげないといけない。
ということで自前のツールで
gitconfig.erb
[core]
excludesfile = <%= ENV['HOME'] %>/.gitignore
てな形で用意しておくことにした。これで Linux でも OSX でもユーザー名が変わっても大丈夫。
2009-02-19 [長年日記]
_ フルチェンケータイ re のアラームは信用ならない
一ヶ月ほど前に変えた新しいケータイである re なんだけど、唐突にアラームが鳴らなくなった。
以前のケータイはバイブ機能が効かなくなって変えたんだけど、なんと、それよりも悪いアラームそのものが効かないという状態。
[これはひどい]
2ch で見てみると同じ症状が出ている人はいるが、それほど有名なものではないのか書き方が悪いのか割と冷たくあしらわれている感じ。そこで「オレもなったよ」と書き込もうと思ったら何が悪いのか書き込めないでやんの。プロバイダがなんか制限してるの?知らんけど。
とりあえず電池パック抜きリセットで回復した*1けど、はっきり言ってこれはかなりタチが悪いよ。アラームがダメになるのはひどいって。
*1 これは翌20日に確認
2009-02-22 [長年日記]
_ Growl でちょっとした時間を無駄なく使う tips
数分や十数分ほど時間が空くときってあると思うんですが、このとき下手に集中を要する作業を始めてしまうと、気づいたときには使える時間をオーバーしてることがありませんか? 私はあります。例えば湯船を溢れさせちゃったり。
どうにかなんないかなと思いましたがハタと思いつき、terminal で以下のように打ちました。
sleep 300 && growlnotify -s -m '風呂'
これでちょっとの間で twitter や feed、メールのチェックが可能です。
そして読みすぎる心配もない。うむうむ。いい感じ。
Windows でも同じような要領で使える便利ツールないかな。
[2009-03-28 追記]
そうかこれはライフハックなのか。
_ Ruby に添付されている rss モジュールのバージョン
ちょっと気になって調べてみた。
| ruby | rss |
| 1.8.5 | 0.1.6 |
| 1.8.6 | 0.1.6 |
| 1.8.7 | 0.2.4 |
| 1.9.0 | 0.2.4 |
ちなみにこの標準添付の rss モジュールは 0.1.8 で atom に対応しているらしい。ということは 1.8.6 以前のバージョンの Ruby で atom を処理したければ別途何かをインストールする必要があるということですな。
cf.
2009-02-23 [長年日記]
_ less 使いが lv を使えるか
長年 less を使っているが、いちばんの理由は
previous page [w] <-> [z] next page
のキーバインドを使っているから。調べたけどこれと同じ操作は lv では実現できないみたい。
man を見てみると
previous page [b] <-> [space] next page
なんてのがある。うーん、[b] が [shift] + [space] ならよかったんだけど。それか
previous page [b] <-> [f] next page
かな。この方がまだ我慢できそうな気がしないでもない。
lv 使いはみんなどのキーバインド使ってるんだろう? 個人的には z/w がいちばん直感的で好きなんだけどね。
2009-02-24 [長年日記]
_ gem メソッドで gem ライブラリのバージョンを指定
21:07:06 wtnabe< ruby で require 時にバージョン指定することってできない のかな 22:23:11 ma2> @wtnabe gemを使わないとダメなんじゃないでしょうか。 22:25:20 wtnabe< @ma2 えっと、require_gem でできるってことですか? 22:30:49 wtnabe< あー Kernel#gem か。なるほど。 23:15:35 wtnabe< @ma2 gem 'GEM_NAME', 'version'; require 'GEM_NAME' で すね。ありがとうございます。
$ ri Kernel#gem
------------------------------------------------------------- Kernel#gem
gem(gem_name, *version_requirements)
------------------------------------------------------------------------
Use Kernel#gem to activate a specific version of +gem_name+.
(snip
例えば以下のように mechanzie 0.8.5 と 0.9.2 がインストールされているとします。
$ gem list -a mechanize *** LOCAL GEMS *** mechanize (0.9.2, 0.8.5)
普通に require すると当然バージョンは 0.9.2 になりますが、
$ ruby -e ' require "rubygems" require "mechanize" puts WWW::Mechanize::VERSION ' 0.9.2
gem メソッドでバージョンを明示するとそのバージョンを使うことができます。
$ ruby -e ' require "rubygems" gem "mechanize", "0.8.5" require "mechanize" puts WWW::Mechanize::VERSION ' 0.8.5
この辺を見ると
RubyGems User Guide | RubyGems Manuals
ある特定バージョンだけでなく、「以降」、「以前」、これらを組み合わせた「範囲」も記述できるようです。なるへそ。
2009-02-25 [長年日記]
_ Ruby の画像ライブラリはまだ何かと面倒
- ruby-gd
- ドキュメントがろくすっぽない。なぜか new_from_jpeg 動かず。
- RMagick
- バージョン2 で ImageMagick 6.3.0 以上を要求するが Debian etch も CentOS 5 もそれ以前のパッケージしか対応してない。
- ImageScience
- 恐らく遠くない将来の本命なんだけど、OS と連動したパッケージが対応するのはまだ先の話。今のところ freeimage 対応の安定感とパッケージへの採用度は今ひとつな感じ。
- mini_magick
- ImageMagick 実行バイナリを呼ぶだけ。
結局 mini_magick を使うことにした。
なんかどれもちょっとまだ早い印象。
_ Capistrano founder burnt out
なんかもう書くことない。(実際書いてるのは5月末だし)
同時にいくつも作りすぎてる気もするね。でも github のおかげもあって fork も楽だし、いい時代だ。
2009-02-28 [長年日記]
_ Ruby の WWW::Mechanize のコツが少し分かってきた
ただし WWW::Mechanize 0.8.x + Hpricot 時代のノウハウ。
- オプション一つで取得した HTML とその解析結果のオブジェクトを全ページ保存できるようにしておく
- Logger に吐かれる HTTP のログもひとまとめに扱えるようにしておく
- 保存された情報を穴が開くほどよく見る
- ブラウザではうまくいくけど Mechanize ではダメな場合、HTTP のログはかなり重要なヒントを与えてくれる
以上。
特に mechanize の取得した HTML とその解析結果のオブジェクトを自動で保存しておくようにすると、どこの何の解釈に失敗しているのかを究明するのがだいぶ楽になる。単に Hpricot を使ったときなんかもそうなんだけど、とにかく取得した HTML は即座に保存しておいた方がいいと思う。サーバにも優しいしね。
で、実際これを思ってから2週間後にできあがった、楽できるフレームがこれ。
個人的にはこれ超使える。
_ elim [whine と附属の whinesend でできますよー。 http://dsas.blog.klab.org/ar..]
_ wtnabe [おぉ、ありがとうございます。試してみます。whinesend には気づいてませんでした。これいいかも。]
_ wtnabe [ping -n SEC localhost ; whinsend.exe の ; の前のスペースが重要なんですね。な..]