Linuxコマンドの日本語マニュアルを(運が良ければ)一発で開く方法 r u feeling lucky?

普段manは英語で読んでるんだけど、たまに日本語で読みたいことがある(bashのマニュアルをさっと見たい時とか)。
日本語マニュアルが手元に無い場合は「Linux JF (Japanese FAQ) Project」にお世話になってたが、一年ほど前にプロジェクトが終了してしまった。現在はアーカイブとして残っているようだ。


これまでは、JFの検索フォームをFirefoxの「この検索にキーワードを設定」で"man"というキーワードで登録していたのだが、アーカイブでは検索機能が動いていないので使えなくなってしまっていた。


マニュアルをさっと引きたいだけなのでGoogle使って、

http://www.google.co.jp/search?btnI=I%27m+Feeling+Lucky&as_sitesearch=ktarn.www.linux.or.jp&as_occt=title&as_q=Manpage+of+%s

をキーワード"man"でブクマし直した。

ポイントは以下の3点

  • site:でktarn.www.linux.or.jp内を検索
    • archive.linux.or.jpでもいいんだけど、そちらは何故かGoogleにインデックスされていないページが結構ある
  • allintitle:で「Manpage of 〜」だけを検索
  • I'm Feeling Luckyで(運が良ければ)一発で開く


あとは今まで通りスマートロケーションバーで「man co」でManpage of COが検索結果に出るのでクリックすれば見れるし、「man bash」だとI'm Feeling Luckyでいきなりマニュアルが開くので、結構便利。




【まとめ】初めてI'm Feeling Luckyをまともに使ったよ!

Re: Time::Piece::MySQL とタイムゾーン - Yet Another Hackadelic

Time::Piece::MySQL とタイムゾーン (訂正あり) - Yet Another Hackadelic
Unix timeにタイムゾーンの概念を持ち込むのは気持ち悪いです。
得られたUnix timeに対してタイムゾーンに対応する目的で数値を加算減算してはいけないと思います。
何故ならUnix timeは「UTCにおける1970/1/1からの経過秒数」だからです。


タイムゾーンJSTになっていて、NOW()はJSTにおける時刻を返しているという前提で話を進めますが、
(当然のことながら、UNIX_TIMESTAMP()はUTCにおける時間を返している)
何が話をややこしくしているかというと、

$ perl -MTime::Piece -MTime::Piece::MySQL -e 'my $t = Time::Piece->from_mysql_datetime("2010-11-05 12:12:47"); warn $t;'
Fri Nov  5 12:12:47 2010 at -e line 1.
これは正しいんですけど、

この出発点から既に正しくないんです。いや、一見正しいように見えるんですけど。

これ実は「Fri Nov 5 12:12:47 2010 UTC」が出力されています。
タイムゾーン情報が無いのでTime::Pieceは渡されたものが「Fri Nov 5 12:12:47 2010 UTC」だと思っています。

  • 「Fri Nov 5 12:12:47 2010 JST(=Fri Nov 5 03:12:47 2010 UTC)」を渡しているつもり

が、実は

  • 「Fri Nov 5 12:12:47 2010 UTC(=Fri Nov 5 21:12:47 2010 JST)」を渡している

のでepochが9時間分ずれた(ように見える)値を返してきます。

この後は連鎖的に話がおかしくなってるだけなので割愛します。


普段Time::Piece使ってないので良く分からないんですが、軽くソースを見た感じc_islocalというのが$ENV{TZ}を見るためのフラグっぽいので、

% env TZ=JST-9 perl -MTime::Piece -MTime::Piece::MySQL -e 'my $t = Time::Piece->from_mysql_datetime("2010-11-05 12:12:47"); $t->[10] = 1; warn $t->epoch;'
1288926767 at -e line 1.

とすると"2010-11-05 12:12:47"をJSTだと思ってくれて、正しくUnix timeを出してくれます。
もちろんTZを変えればちゃんとUnix timeも変わってくれます。

($t->[10]とか$t->tzoffsetとかを出力してみると何となくわかるかも)

ただ、文字列変換(warn $t)したときにTZに応じて変わってくれないっぽいので、Time::Pieceはイケテないライブラリだと思います。
(Time::Pieceを良く分かってないので、もしかしたらちゃんとタイムゾーンを扱う方法があるのかも知れません)



なお個人的には、時間を扱うライブラリはparse時にタイムゾーンを指定できるようしておいて欲しいなーと思います。その方が混乱が少ないかと。
それからタイムゾーン周りはperlUNICODEの扱い(基本的に全てutf8 flaggedで扱って、出力するときにencodeする的な話)と同様に、基本的に全てUTCでやり取りして、後に出力する時だけ適切なタイムゾーンを設定して出すようにすれば、色々な悩みは無くなるんではないかなーと思います。

この件と直接関係ないけども、
id:kits perl -MTime::Piece -le '$t=Time::Piece->strptime("2010-11-05 12:12:47 +0900","%Y-%m-%d %H:%M:%S %z"); print $t->epoch' のようにすればいいように思う。
それ試してダメだったのにそんなバカな…と思ってもう一度試してみた。Time::Pieceアップデートしたら確かに↑の通りだった。
% perl-version Time::Piece
Time::Piece = 1.15
% perl -MTime::Piece -le '$t=Time::Piece->strptime("2010-11-05 12:12:47 +0900","%Y-%m-%d %H:%M:%S %z"); print $t->epoch'
Error parsing time at /usr/lib/perl5/5.10/i686-cygwin/Time/Piece.pm line 470.

% perl-version Time::Piece
Time::Piece = 1.20
% perl -MTime::Piece -le '$t=Time::Piece->strptime("2010-11-05 12:12:47 +0900","%Y-%m-%d %H:%M:%S %z"); print $t->epoch'
1288926767

colordiffの文字単位版ccdiffを作ったid:yappo++

diffに色付けしたかったけど、colordiffみたいな行単位じゃなくて、文字単位で色付けしたい。
id:yappoString::Diff - Simple diff to String - metacpan.org使ってccdiff(charactor color diff)というのをでっちあげた。


ってか後から単語単位の方がいいかなと思った。
でwdiffとcolordiffの組み合わせとか試してみたけど、

% cat foo.patch | wdiff -d | colordiff

だと、日本語の扱いもおかしくて何か出力が微妙で…。
Text::WordDiff - Track changes between documents - metacpan.orgも軽く試したけど「行単位で単語単位(説明難しい…)」ができないっぽくてやめた。
String::Diffより最適なモジュールがあるかもしれんけど探すのめんどいのでとりあえずこのままで。


使い方

以下のデータががあるとき。

% cat foo.old
abc
% cat foo.new
azc
% cat foo.patch
--- foo.old     2010-11-04 12:27:27.040992700 +0900
+++ foo.new     2010-11-04 12:27:33.149776700 +0900
@@ -1 +1 @@
-abc
+azc

1. unified形式のパッチを渡す

% diff -u foo.old foo.new | ccdiff

% cat foo.patch | ccdiff

% cat - | ccdiff
パッチ貼り付け
^D

svn diffでもいい。


2. またはdiffと同じようにファイル(およびdiffのオプションも可)を渡す(内部でdiffを呼んでる)

% ccdiff foo.old foo.new

出力はどれも同じで以下のようになる。

--- foo.old     2010-11-04 12:27:27.040992700 +0900
+++ foo.new     2010-11-04 12:27:33.149776700 +0900
@@ -1 +1 @@
-abc
+azc

現在のところunified形式しか受け付けません。

#! perl
#
# $Id: ccdiff 1008 2010-11-04 10:16:41Z hyoshida $
#
eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
  if 0;
use strict;
use warnings;
use version; our $VERSION = qv('0.0.1');

use autodie;
use IO::Pipe;
use String::Diff qw(diff);
use Term::ANSIColor;

%String::Diff::DEFAULT_MARKS = (
    remove_open  => ( color 'red' ),
    remove_close => ( color 'reset' ),
    append_open  => ( color 'green' ),
    append_close => ( color 'reset' ),
    separator    => q{},
);

if ( 2 <= @ARGV ) {

    # TODO: deal with existing STDIN
    open STDIN, q{<&=}, IO::Pipe->new->reader( 'diff', '-u', @ARGV );
    undef @ARGV;
}

my @s = (q{}) x 2;
foreach (<>) {
        /^[-]/msx ? ( $s[0] .= $_ )
      : /^[+]/msx ? ( $s[1] .= $_ )
      : do {
        print diff(@s), $_;
        @s = (q{}) x 2;
      };
}
print diff(@s);

__END__

=head1 NAME

ccdiff - a tool to colorize by the character diff output

=head1 USAGE

    $ ccdiff foo.old foo.new

    $ diff -u foo.old foo.new | ccdiff
    $ cat foo.patch | ccdiff

=head1 DESCRIPTION

a tool to colorize by the character diff output

=head1 REQUIRED ARGUMENTS

None.

=head1 OPTIONS

None.

=head1 DIAGNOSTICS

None.

=head1 EXIT STATUS

None.

=head1 CONFIGURATION

ccdiff requires no configuration files.

=head1 DEPENDENCIES

L<String::Diff|String::Diff>

=head1 INCOMPATIBILITIES

None reported.

=head1 BUGS AND LIMITATIONS

No bugs have been reported.

=over

=item TODO: add copied context support

=item TODO: add ~/.colordiffrc support

=item TODO: add multibyte support

=back

=head1 AUTHOR

Hironori Yoshida <yoshida@cpan.org>

=head1 LICENSE AND COPYRIGHT

This module is free software; you can redistribute it and/or modify it
under the same terms as Perl itself. See L<perlartistic|perlartistic>.

=cut
  • STDINの処理の辺り自信が無い。closeしないといけないのかとか<&=とか。
  • 最初whileで逐次処理してたけど、これだとcat - | ccdiffの時に逐一出力されてしまって都合が悪いのでforeachに置き換えた。

mintty-0.9.2-1がインスコ時にエラーを吐いてスタートメニューにショートカットが作成されない

mintty-0.9.2-1がインスコ時にexit(3)的なエラーを吐いてスタートメニューにショートカットが作成されない。
いじってたらこんな感じでできた。

--- etc/postinstall/mintty.sh.orig      2010-11-04 11:03:50.086733700 +0900
+++ etc/postinstall/mintty.sh   2010-11-04 11:04:30.855356100 +0900
@@ -1,6 +1,6 @@
 PROGS=$(/bin/cygpath -P $CYGWINFORALL)
 /bin/mkdir -p "$PROGS/Cygwin" &&
-/bin/mkshortcut -n "$PROGS/Cygwin/mintty" -a - -d Terminal /bin/mintty &&
+/bin/mkshortcut -P $CYGWINFORALL -n "Cygwin/mintty" -a - -d Terminal /bin/mintty &&
 if [ "$CYGWINFORALL" ]; then
   /bin/chmod a+r "$PROGS/Cygwin/mintty.lnk"
 fi

うーん。mkshortcutもしくは自分の環境がおかしい気がする。

っていうかね。結局ckの方が、軽くて速くて文字コードキーバインド・マルチシェルなどなど色々便利だから、ck使い続けるよ!

埋め込まれたiframeをリロードさせる方法

iframeを更新させるためにこんな処理が書いてあって、

<iframe id="foo" name="foo" src="/bar.html"></iframe>

<a target="foo">更新</a>

一応動くには動くんだけど、a要素の使い方がなんだかなーと。

軽く調べても出てこなかったので、ちょいと試してみたら

document.getElementById("foo").contentWindow.location.reload();

でいけたっぽい。JavaScriptだけど。(ちなみにreload(true)とすればスーパーリロードになるよ)


"contentWindow.location.reload()"で調べ直したら色々出てきた。

ハインリッヒの法則 - 1つの障害・バグ・ERRORの背後には29のWARNINGがあり、その背景には300の異常が存在する

ハインリッヒの法則 (ハインリッヒのほうそく、Heinrich's law) は、労働災害における経験則の一つである。1つの重大事故の背後には29の軽微な事故があり、その背景には300の異常が存在するというもの。ハインリッヒの(災害)三角形(トライアングル)(定理)又は(傷害)四角錐(ピラミッド)とも呼ばれる。

これって開発にも当てはまるよね。割合は違うと思うけど。


インデント・変数名・ファイル名がおかしかったり、コンパイラがWARNING出してたり、良く見ないと理解出来ないロジックがあったりなど、
とりあえず動いちゃうから一見些細な事だと思いがちだけど、それが積み重なって変なことになる。
「そんな細かいところ、どうでもいいじゃん」って言っちゃうプログラマーが、やはりバグを引き起こす確率が高い。
で、「原因はちょっとしたミスでした」って言う。


だいたいバグや障害の原因を調べると、結局は単純ミスであることが多い。(重大なミスというのはすぐ分かるからね)
単純で小さなミスを防ぐことこそ、重大な事故を防ぐ唯一の手段ではないかな。(自動化は強力だから推し進めるべし)

jQuery.getでtypeを指定しないと、MIME-Typeによって挙動が変わってしまう。

(jQuery1.4.2)
ある日、JSONテキストを受け取ってevalする処理がエラーを吐くようになった。こういうコード。

jQuery.get('/foo.json',
           function(json) {
               var foo = eval('(' + json + ')');
           });

思い当たるのは、Content-Typeがtext/plainだったのをapplication/jsonに変更したこと。
実際にそれが原因だったのだけれども。

/* MIME-Type: text/plain       */jQuery.get('/foo.json', function(json) {typeof json == 'string';});
/* MIME-Type: application/json */jQuery.get('/foo.json', function(json) {typeof json == 'object';});

/foo.jsonMIME-Typeがtext/plainだとコールバックに渡ってくるのは文字列なんだけども、
application/jsonだとオブジェクトが渡ってきた。(それを更にevalしちゃってたのでエラーになっていたという話)


安直にevalを外すという修正をしてしまうと対象リソースのMIME-Typeに左右されるようになってしまうので、getJSONに統一するようにした。
getJSONは対象リソースがJSONだと明示するメソッドで、

/* MIME-Type: text/plain       */jQuery.getJSON('/foo.json', function(json) {typeof json == 'object';});
/* MIME-Type: application/json */jQuery.getJSON('/foo.json', function(json) {typeof json == 'object';});

のように、MIME=Typeがどうなっていようとコールバックにはオブジェクトが渡ってくる。


ってかこれは

/* MIME-Type: text/plain       */jQuery.get('/foo.json', function(json) {typeof json == 'object';}, 'json');

のようにjQuery.getにタイプ'json'を渡してあげるのと同じことなんだけどね。
毎回'json'を渡すよりは、getJSONが用意されてるんだからそっち使った方が良いかなーと。