3歳児がするコンピュータの操作

うちの息子は戦隊モノ (今ならゲキレンジャー) や仮面ライダー (こちらは電王ですね) が大好きで仕方ないのです。 私がそれらの Web サイトを見せると当然ながらあっちこっちをクリックするようにねだってきます。

ならばとマウスの使い方を教えると、きちんとクリックすることを覚え、スクロールも真ん中のダイアル (古いマイクロソフト製マウスを使っています) を使って上手にできるようになりました。

操作を覚えた息子の横でただ付き添っているだけなのはちと面倒なのですが、 目を離すと関係ないアプリケーションを起動して、どう操作すれば出てくるのかわからない、それでいて危険な選択を迫るダイアログボックスを表示してくれたりするので困ります。 それならばと息子専用のアカウント (パスワードなし) を作ってブラウザのお気に入りにそれらのサイトを登録してやると、 ログイン画面から自分のアイコンを選んでログインし、ブラウザを起動してブックマークから目的のサイトへ到達することを覚えました。

続いて PDF でできた塗り絵を印刷する操作を覚えました。

そのうち、ログイン画面のアイコンを変えたり、パスワードをつけたり (「りりり」とか「ろろろ」とか簡単ですが) し始めて、無駄に頻繁にこれらを変更しています。 ログオフやらシャットダウンやらも出来るのですが、悲しいかな、漢字が読めないため、操作につまることもよくあります。

それにしても好きこそものの上手なれ、戦隊モノのホームページを見るためにちょくちょくパソコンを使い、 段々と新しいページへの辿りつき方や新しい操作を覚えていきます。 親としては今のうちからあまりのめり込んで欲しくはないし、目も悪くなりそうで心配なところはあるのですが、 テレビをダラダラ受動的に見るよりは能動的で良い気もしています。 キーボードの配列っていつ頃教えるんでしょうねぇ… (爆)

こんな息子は来月4歳になります。

Cygwin 上でのシリアル端末エミュレータと expect

例えばネットワークの変更作業を終えた後にもろもろのステータスを確認するログを取得するときなど、大量の機器に対しお決まりの一連のコマンドを投入したいときがあります。 そんなとき私の周囲の人々は Tera Term のマクロを駆使してコマンドラインインターフェイス上での一連のコマンド実行を自動化するわけですが、 私はいまさら Tera Term のマクロを覚えるよりは手許にある expect のスクリプトをちょっと直して済ませたいと思ってしまうわけです。 マクロの類など使わずに、実行するコマンドを羅列したテキストエディタから端末エミュレータへコピー&ペーストするという手もありますが、 このやり方を取ると一般に機器の応答を待たず一連のテキストをペーストしてしまうので、何かの拍子にペーストしたコマンドがきちんと認識されずエラーが起こるというのはありがちなことです。 そもそもコピペの連続などエンジニアの作業としてはどうなのかという問題 (?) もあります。

さて、expect を使いたい時は Cygwin の expect を使います。ネットワーク越しにアクセスできれば /usr/bin/telnet.exe を使ってログインをした後に機器のコマンド実行をするスクリプトを作って流すことができます。 しかし、もろもろの理由でシリアルケーブルを使ってコマンド実行しなければならない時もあります。 Tera Term ならばネットワーク接続でもシリアル接続でもどちらでも問題ないのですが、expect を使うときは telnet の代わりにシリアル端末エミュレータを使わなければなりません。 「シリアル端末エミュレータ」という言葉はかなりニッチな分野でコレという決定的なソフトが無いように思います。 ですので選択が難しいところですが、私の場合は jerm を使っています。

何故 jerm だったのかは記憶が定かでないのですが、とりあえずコンパイルして使っていて問題がないのでそのまま使い続けています。 ただし、コンパイルにはそれなりにソースを修正しています。 jerm-8095 用のパッチファイルはこちらです。 そのうち blog で取り上げようと思いつつコンパイルをしたのが既に1年以上前になってしまい、詳細は覚えていないのですが、 今その内容を見ると苦労してコンパイルした後が窺えます。 単純にシリアルターミナルエミュレータとして動かすことのみを目的としたパッチファイルですので、他の付加機能がきちんと動くかは試していませんのでご注意ください。 getaddrinfo-1.6.3.tar.gz を利用させていただきましたが、これはパッチファイルの中に含まれています。

さて expect を使ったコマンドの実行例です。 とりあえず、サンプルレベルですが、以下が expect スクリプトと実行するネットワーク機器のコマンドファイル (Cisco Catalyst 用) の例です。enable 用パスワードは cisco としています。また、COM2 (=/dev/ttyS1) を利用しています。 見てお分かりのように、シリアル通信を開始してプロンプトを出し enable する手順を、 while 文を用いてプログラム化しています。

docmd.exp

set timeout 2
match_max 100000
if {[llength $argv]>0} {
set filename [lindex $argv 0]
set enablep "cisco"
set fp [open $filename r]
set pid [spawn /usr/local/bin/jerm -r xnrn /dev/ttyS1]
set done ""
while {"$done" == ""} {
expect {
">" {
set timeout -1
send -- "enable\r"
expect "Password: "
send -- "$enablep\r"
}
"#" {
set done 1
}
timeout {
send -- "\r"
}
}
}
while {![eof $fp]} {
set cmd [gets $fp]
send -- "$cmd\r"
expect "#"
}
send -- "exit\r"
exec kill $pid
close $fp
close
}

status.cmd

terminal length 0
show clock
show interface
show route
show logging

この2つを用いて以下のように実行すれば、status.log に実行結果を残すことができます。

expect docmd.exp status.cmd | tee status.log

expect を使うとシェルスクリプトと組み合わせて複数の機器にパラメータを調整しながら telnet でコマンド実行したりということも書きやすいので、 重宝しています。 というかそのような用途に Tera Term のマクロより expect + sh スクリプトを選ぶ私が嗜好が今の時代だと特殊かも知れませんが。 expect についての情報は多くないのですが、Tcl の拡張なので文法は Tcl について調べればオッケーです。


2007. 8. 10 追記
コメント欄にある通り、 jerm 作者の方が、パッチの内容を取り込んだ新バージョンをリリースしてくださいました。 バイナリ版も合わせてリリースされていますので、Cygwin でシリアル通信プログラムを探している方はまず jerm を試してみてはいかがでしょう?

2011. 7. 29 追記
少し前perl の expect モジュールを見つけました。 私のように tcl よりは perl の方が嬉しいという人はチェックしてみてください。

マザーボード上のコネクタを用いた USB ポート増設

家で使っているデスクトップマシンのマザーボードは AOpen AX4SG-UL なのですが、 このボードにはバックパネルに4つの USB ポートがあり、更にマザーボード上に USB ポート2個分のコネクタ×2ヶがあります。 これまではバックパネルの4つのみ使っていたのですが、USB 機器が増えたので使えるポートを増やしたくなりました。

そこでマザーボード上のコネクタを有効利用しようと思い立ち、増設用の USB ポートを買おうと決心したのですが、調べてみるとピン配列に標準がないようで下手をすると間違って互換性のないピン配列のものを買ってしまいそうです。 慎重を期さなければと心に留めつつ、まずは帰宅途中に寄り易いビックカメラで物色したのですが、ちょうど良いものがあったので購入しました。 Groovy の GR-US006 という製品です。

ピン配列

マニュアルを参照するとマザーボードのピン配列は上の図の通りなのですが、これと全く同じ配列のコネクタが2つ使われていて、4つの USB ポートを 3.5 インチベイの中に組み込むことができます。 これを見つけるまでは背面のスロットに挿すものを想定していたのですが、一時的に挿す USB 機器の場合はフロントにポートがある方が使い勝手が良いですね。

ただし、3.5 インチベイの中に4つのポートが並んでいるため、ポートの間隔は必要最低限しかないので注意が必要です。 USB ケーブルを挿すならば問題はありませんが、例えば私の持っている初代 iPod Shuffle を挿すと隣のポートは使えなくなります。 まあ、前後合わせて8つのポートをフルに使うことはないような気がしますが。

価格は \2,310 でした。 チップの載った PCI バス用増設カードが買えてしまう値段なので気分的にしっくりこないのですが、ケーブル類はそれなりに値が張るので、フロントにポートがつくことを考えればこの程度の出費は仕方ないですよね。

bogofilter を正しく使おう – 2007年 6月版

さて、bogofilter 使用環境での spam 登録/ham 登録/判定のためのスクリプトの改訂版です。 このスクリプトは元々 Mew のマーク付けに呼び出して使うために書いています。 何故このスクリプトが必要かというと、nkf では本文が base64 等でエンコードされたメールをきちんとデコードできないからです。 Ruby で書かれた前処理のフィルタ (その1その2) は見つかったのですが、perl のものが見当たらないので自分で書いてみたのです。外部コマンド実行のオーバーヘッド削減を目的として Text::Kakasi や NKF モジュールを用いています。

前回から何が変わったかというと、MIME の階層をきちんと辿るようにしました。前回のものはこれが不十分でした。 また、コンテンツタイプがテキスト以外のものは Content-Type フィールドを表示して、学習に生かせるようにしました。実行時の各種オプションも新設しました。

#!/usr/bin/perl
use Email::MIME;
use NKF;
use Text::Kakasi;
use Getopt::Std;
my $nkfopt  = "-e";
my $bogoopt = "";
my $printmode = 0;
sub mime_body {
my $o = shift;
my @p = $o->subparts;
my $m = "";
if (@p > 0) {
foreach my $so (@p) {
$m = $m . mime_body($so);
}
}
elsif (!defined($o->content_type) || $o->content_type =~ /text/i) {
$m = $m . nkf($nkfopt, $o->body);
}
else {
$m = $m . $o->content_type . "\n";
}
return $m;
}
local $/;
my $k = Text::Kakasi->new;
$k->set("-w");
getopt('snp');
if (defined($opt_s)) { $bogoopt = "-s"; }
if (defined($opt_n)) { $bogoopt = "-n"; }
if (defined($opt_p)) { $printmode = 1;  }
LOOP: foreach $filename (@ARGV)  {
open(I, $filename) || next LOOP;
my $message = <I>;
my $parsed = Email::MIME->new($message);
$message = nkf($nkfopt, $parsed->header_obj->as_string . "\n") . mime_body($parsed);
my $tokenized = $k->get($message);
if ($printmode) {
print $tokenized;
}
else {
open(O, "| bogofilter $bogoopt") || die("can't execute bogofilter");
print O $tokenized;
close(O) && print "$filename\n";
}
close(I);
}

このスクリプトを bogo として、使い方を簡単に説明します。 そのフォルダのメールをスパムとしてデータベースに登録するには次のように呼び出します。

bogo -s -- *

そのフォルダのメールをハムとしてデータベースに登録するには次のように呼び出します。

bogo -n -- *

"-p" オプションは bogofilter に喰わせる前のメールデータを標準出力に出力します。 kakai による分かち書きの結果も確認できます。

bogo -p -- *

引数でオプションをつけずファイル名のみ渡すと、指定したファイルのうち spam と判定されたメールのファイル名のみ標準出力に出力します。 これを Mew のマークに使います。

bogo *

利用している perl のメール関連パッケージは以下の通りです。この順で "perl Makefile.PL; make; make install" を実行しインストールしました。

  • MIME-Types-1.20
  • MIME-Base64-3.07
  • Email-MIME-ContentType-1.014
  • Email-MIME-Encoding-1.311
  • Email-Simple-1.999
  • Email-MIME-1.859

この他に Text::Kakasi と NKF を用いています。

メール関連のこの辺りのモジュールは使いやすいと思います。 日本語のサイトで取り上げている例は少ないようですが、このコードが処理の参考になればと思います。

Cygwin 上で bogofilter を再インストール

ハードディスク換装に伴い Cygwin もインストールし直しとなり、bogofilter を最新のソース再コンパイルしました。 前回紹介した時とバージョンやら configure のオプションやらが若干異なるので記録しておきます。導入したバージョンは bogofilter-1.1.5 です。

まず、Cygwin でデフォルトではインストールされない以下のパッケージをインストールしておきます。

db4.3
libdb4.3
libdb4.3-devel
gsl
gcc
make

私の場合、ソースをコンパイルする前にリンクをいくつか張る必要がありました。

cd /bin
ln -s /bin/bash sh
cd /lib
ln -s libdb-4.3.a libdb.a
ln -s libdb-4.3.dll.a libdb.dll.a
ln -s libdb-4.3.la libdb.la
ln -s libdb_cxx-4.3.a libdb_cxx.a
ln -s libdb_cxx-4.3.dll.a libdb_cxx.dll.a
ln -s libdb_cxx-4.3.la libdb_cxx.la

さて次はコンパイル、インストールですが、configure で db パッケージのヘッダファイルを明示的に指定する必要があります。

./configure CPPFLAGS=-I/usr/include/db4.3
make
make install

これで無事 bogofilter がインストールされます。最近は /usr/local/etc/bogofilter.cf に次のように書いて判定時のしきい値を調整しています。

spam_cutoff = 0.80

bogofilter を呼び出すスクリプトもいろいろ手を入れていますが、これは次の記事に書きます。

沖縄密約―「情報犯罪」と日米同盟

「日本は米国の属国」というフレーズはよく聞きますが、 漠然と日本はアピールの仕方が下手なだけだと思い、深刻に考えてはいませんでした。 また、「安保」と聞くと条約よりも「安保闘争」のイメージが強く、 この闘争を知らない世代の私にとっては「安保」という単語はイデオロギー色が強く自分とは縁のない事柄との認識でしたし、 沖縄も「内地」に住む私にとっては観光地のイメージが強いです。 しかしこの本を読むと確かに日本はアメリカの属国でいいようにされていることがわかります。 そして、いま行われている米軍再編が日本の負担を減らすものでは全くないことも。

沖縄返還交渉の最初で「核抜き」にこだわったためにつまづいた流れが、そのまま今現在まで続いていて私たちにとっても他人事ではないです。 例えそれが小さなつまづきであったとしてもそのまま事態が進んでしまうと、後になればなるほどその失敗を取り返すことは困難になりますが、この本を読む限りでは日本は戦略的に交渉を遂行する能力が全く無く、アメリカのいいように流されているだけのように思えます。 この流れを止めるためにも多くの人が本書を手に取ることを願い、日本における権力が民衆の特性を熟知していることがことを指摘した次の文を引用しておきます。

統治する側にとって、これほど好都合なことはなく、彼らは、民衆の弱点、すなわち瞬間的には反応するが、一過性ですぐに終わってしまうという性向を知りつくしている。

また、この本を読む上で「西山太吉事件」のあらすじも知っておくべきでしょう。

「クロールに関する情報」、「ページ分析」が表示されない件

Google のウェブマスターツールでサイトマップをきちんと登録したものの、 「統計」の「クロールに関する情報」と「ページ分析」がこれまでずっと「現在、データを表示できません」の表示のままでした。 それがある日気がつくと表示されるようになっていました。 恐らく sitemaps.xml ファイルを登録して半年ぐらいは経過していたと思います。 きっかけは特に思い当たることはなく (先の記事に記した DOCTYPE 宣言の変更をする以前から表示されていたように思います) 単に時間がかかっただけのように思います。 Web 検索すると他にもこの2つが表示されない例は見つかるのでそういうものなのでしょう。

この他にも Google のウェブマスターツールは微妙なところが多いです。 私の場合、「診断」の「クロール率」は1ヶ月前ぐらい迄しかグラフ表示されず最近の情報は表示されませんし、 「統計」の「クエリに関する情報 」は「過去 7 日間のデータの平均」といいつつ2、3週間同じ内容が表示され続けたりします。実際に過去 7 日間の平均であればそのようなことはないはずなのですが…

まあ場末のサイトではそのようなことになってしまうのかも知れません。 そのような時はサイトマップ登録のためのツールと割り切るしかないように思います。

Google で「日本語のページを検索」すると結果表示が少ない問題について

最近、この blog のアクセス数が目に見えて増えてきました。 嬉しいことではあるのですが、どこかで紹介された様子はないし、 一体何が起こったのだろうといぶかしんでいたのですが、 どうやら Google の「日本語のページを検索」したときに引っかかるページが増えてきたのが原因のようです。

以前、 "site:" オプションを指定してこのサイトに対し「ウェブ全体から検索」したときは3桁のページが引っかかるのに「日本語のページを検索」すると1桁しか結果表示されないのに気づいたことがありました。 全記事は日本語で書いています。 恐らくここに blog を移してからずっとそういう状態が続いていたのでしょう。 この問題を解決しようと調べてはみたものの、 Web 上に「これだ!」と特定できるようなような情報はなかったので問題を放置したままの状況でした。

ところが最近になって調べてみると「日本語のページを検索」でも同程度の数の検索結果が表示されるようになりつつあります。 この間何をしたかというと思いつくのは Google AdSense を導入し、それに伴い DOCTYPE 宣言を HTML から XHTML に変えたことぐらいです。(今は XHTML に変えたものの古いアトリビュートを使っているのを全て直せていないというあまり誉められない状態なのですが… はい、少しずつ直していくつもりです。)

関係しそうなところでは HTML の時は、

<html lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=euc-jp">
</pre>

と指定していました。XHTML にした後はこれを、

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja">
<head>
<meta http-equiv="content-type" content="text/html; charset=euc-jp" />

としています。

こちらの調査 を見るとかなりの割合の人が「日本語のページを検索」で検索しているようです。 どうりでアクセス数が増えるわけです。 FC2 ブログには同様の症状の blog が少なからず存在するように見受けられますが、誰か同じことをして「日本語のページを検索」の結果が増えるか試してみませんか?