読者です 読者をやめる 読者になる 読者になる

Rich Lab. Blog

「まつらリッチ研究所」の研究の一環で、はてなブログ上にブログを公開。でもなぜか買い物カゴが……。はてブはそんな機能あったっけ?

Shell Script ライトクックブック2014 第二版

昨年末の冬コミで発行したShell Scriptライトクックブック2014、第二版をコミケットスペシャルで発売します。

f:id:richmikan:20150324165114j:plain

POSIX原理主義シェルスクリプトレシピ集

Shell Scriptライトクックブック 2014 第二版

2015年3月28日 発行(コミケットSP6 1日目)

頒布価格:1200円

ページが増えて154Pに

目次商品ページ

現在、カゴに冊入っています

(Safariをお使いの方はコチラで注文)

第二版の変更点

詳細は目次をご覧ください。と済ませるのもあんまりなので、ポイントを記します。

計10個のレシピが、追加 or 修正

シェルスクリプトを書いていると次から次へとレシピが増えますが、今回も少し増えました。例えば、Base64エンコードとデコードです。Linux等ではBase64のコーデックたるbase64コマンドが始めから入っていて不要なレシピかもしれませんが、POSIXの範囲で実装した話を紹介しています。これによって、他の環境でも安心してBase64が扱えます。

Base64との相互変換を実現するは、バイナリーコードを扱える必要があります。ところが、AWKの変数(GNU版除く)やシェル変数(zsh除く)ではそれができません。では一体どうやってシェルスクリプトバイナリーコードを扱うのか、という話もレシピとして追加しました。

その他、どの環境でも使えるシェルスクリプトを書くためのレシピを多数追加加筆しました。

より強化したPOSIX原理主義

ところで、なぜBase64を扱うレシピを追加したのか。それは、メール送信のレシピからnkfコマンドを葬り去るためです。

これまでは、UTF-8文字をSMTPサーバーが許容する7ビット文字セットであるJISコードに変換するためにnkfを利用していました。しかし、Base64エンコードをして英数字だけにしてしまえばUTF-8のまま送ることが可能になるというわけです。また、Subject:などに置く日本語文字列をBエンコードISO-2022-JPBase64エンコード)するためにもnkfコマンドを利用していましたが、これもUTF-8のままBase64変換すればよいわけで、base64コマンドという車輪の再発明によってこちらからも排除することに成功しました。

さようならnkf……、他にもmktempやwhichをPOSIXの範囲で実装することに成功したため、それらに頼っていたレシピもよりPOSIX原理主義忠実なものになりました。

コミケットスペシャル6で初売り

完成した第二版は、3/28(土)から開催されるコミケットスペシャル6で頒布します。スペース番号は、1日目 K-58bです。

通販もやってます

通常のコミケではないし……、遠いし……、行けないよ。という方もご安心を。通販やってます。この通販のためのプログラムは、本書で紹介したレシピをふんだんに活用し、シェルスクリプトで作られたものです。本書レシピの実力の程を確認するためにも、このサイトの通販を是非ご利用ください。(Safari等、このサイトのカゴ入れボタンがうまく機能しない方はコチラへ)

 

 

←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。

東京メトロの列車接近情報を返すWebAPIをシェルスクリプトで叩く

既にいろいろなところで話に上っているけど、東京メトロ「オープンデータ活用コンテスト」というのをやっている。

時刻表や駅の設備といった静的な情報はもちろん、リアルタイムの列車位置なんかも公開するという大盤振る舞い。「これで役立つアプリを作ってね」ということなのだが、じゃあ俺がシェルスクリプトで何か作ってやろうじゃないかと、いうことでパイプを駆使した活用プログラムを作ってみた。

接近情報表示コマンド「メトロパイパー」

f:id:richmikan:20140921114151j:plain

一般的な意味の「パイパー」とは、
こういう人のことを言うらしい

というわけで作ってみたプログラム、その名は「メトロパイパー」。パイパーというと、本来は右の写真のような男の娘を意味するらしいのだが、ここでのパイパーとは「UNIXシェルのパイプを操る者」と「地下鉄のパイプ(=路線)を覗く者」という意味にしている。

各種情報はここ以外にも下記のサイトに置いておいたので参考にしてね。

ところで「接近情報」って?

まず接近情報とは何かだが、駅のホームへ行くとそこの電光掲示板に表示される、

【こんど】快速 東葉勝田台
【つぎ 】各停 西船橋
※ 「こんど」&「つぎ」なんていつの時代だ

とか

前々駅 -◆- 前駅 --- 当駅

というアレだ。

でも、あの情報がその駅に居なくても見られたら便利だよなー、とまえまえから思っていた。例えばこんなシーンはないだろうか。

  • 時間ギリギリにホームに着いたけど、目的の電車が来ない!遅れてるのかな?それともやっぱり出発しちゃったのかな?(あぁ、先の駅の接近情報が見られれば……)
  • 急行南栗橋行間に合わなかったなぁ……。次の東武線直通はどの駅まで来てるんだろう。
  • あ、特急ロマンスカー霞ヶ関駅あたりに来てるな。よし、じゃあそろそろ帰宅の準備して表参道駅へ行くか。

という具合に、今いる駅の、先や、もっと手前の駅の接近情報、あるいは駅にいなくてもこれから行く予定の駅の接近情報ってわかれば便利でしょ。使い方は直感的にわかるように作っているつもりなので使ってみてね。

UNIX哲学とPOSIX原理主義溢れるソースコード

このプログラムの特徴は何と言っても、中身のほとんど全て*1シェルスクリプト+UNIX標準コマンドで書かれているということだ。しかもUNIX哲学の思想を随所に採り入れ、パイプを多用している点だ。

そのいくつかを紹介しよう。

JSONテキストを行列指向に変形して捌く!

まずはソースコード「SHELL/VIEW_METROLOC_0.SH」を見てもらいたい。

######################################################################
# 列車ロケーション情報API呼び出しと、キャッシュ作成
# (キャッシュの有効期限が切れているならば)
######################################################################
:
# --- 有効キャッシュがなければ作る(タイムスタンプは有効期限日時に設定)
[ $cache_is_fresh -eq 0 ] && { curl -s $url | parsrj.sh > "$File_cache"; }
:
:

######################################################################
# API取得データ(列車ロケーション情報の取得)の加工
######################################################################

# --- 必要な項目・区間&方面のみに絞り込んだ在線位置マスターファイルを作る
cat "$File_cache" |
sed 's/^\$\[\([0-9]\{1,\}\)\]\.[^:]\{1,\}:/\1 /' |
awk '$2=="railDirection" {$2=1;print;} #
$2=="fromStation" {$2=2;print;} #
$2=="toStation" {$2=3;print;} #
$2=="trainType" {$2=4;print;} #
$2=="terminalStation"{$2=5;print;} #
$2=="trainOwner" {$2=6;print;}' |
sort -k1n,2n |
awk '{print $3}' |
awk 'NR%6!=0{printf("%s ",$0)} NR%6==0{print $0}' |
# 1:方面コード 2:発車駅コード 3:到着駅コード 4:種別コード 5:目的駅コード 6:車両所有業者コード
:

これは実際にAPIを叩いて値を解析しているコードの一部だ。

東京メトロの今回のオープンデータAPIJSON-LDという形式で情報を返してくる。そこで拙作のJSONパーサー"parsrj.sh"(→解説)で、(1)値の位置、(2)値という、各行2列で構成されるテキストに変換し、それをさらにAWKを使って(1)方面コード(上り下り的なもの)、(2)発車駅コード、(3)到着駅コード、(4)種別コード、(5)目的駅コード、(6)車両所有業者コード、という6列のデータに変換している。

こうやってJSONを一旦行列指向のフォーマットに変換してしまえば、あとはgrepAWKで絞り込んだり加工したり……と、リレーショナルデータベース的な操作が自由にできる。

JOINコマンドでマスターデータをハメ込む

「リレーショナルデータベース的な操作」と言ったからには当然JOINもできる。例えば、同じソースコード「SHELL/VIEW_METROLOC_0.SH」の下記の部分を見てもらいたい。

# --- コードを名称化し、列車存在位置から列車名を引くマスターファイルを作る
cat $Tmp-this-rw-dir-loc |
# 1:現在居る3桁駅ナンバー(3桁目は0または5で、5は中間にいることを表す) 2:種別コード
# 3:目的駅コード 4:車両所有業者コード #
sort -k2,2 |
join -1 1 -2 2 -a 2 -o 2.1,2.2,1.2,2.3,2.4 $Homedir/DATA/METRO_VOC_MST.TXT - |
sed 's/\([^. ]\{1,\}\) /\1 \1 /' |
awk '{print $1,$3,$4,$5}' |
# 1::現在居る3桁駅ナンバー(3桁目は0または5で、5は中間にいることを表す) 2:種別名
# 3:目的駅コード 4:車両所有業者コード #
sort -k3,3 |
join -1 1 -2 3 -a 2 -o 2.1,2.2,2.3,1.2,2.4 $Homedir/DATA/METRO_VOC_MST.TXT - |
sed 's/\([^. ]\{1,\}\) /\1 \1 /' |
awk '{print $1,$2,$4,$5}' |
# 1:現在居る3桁駅ナンバー(3桁目は0または5で、5は中間にいることを表す) 2:種別名
# 3:目的駅名 4:車両所有業者コード #
sort -k4,4 |
join -1 1 -2 4 -a 2 -o 2.1,2.2,2.3,2.4,1.2 $Homedir/DATA/METRO_VOC_MST.TXT - |
sed 's/\([^. ]\{1,\}\) /\1 \1 /' |
awk '{print $1,$2,$3,$5}' |
# 1:現在居る3桁駅ナンバー(3桁目は0または5で、5は中間にいることを表す) 2:種別名
# 3:目的駅名 4:車両所有業者名 |
sort -k1,1 > $Tmp-this-rw-loc

APIから送られてくる接近情報データは人間に分かりやすい名称ではなく、各種コード文字列になっている。これを人間向けにするなら、各種コードに対応する名称の記されたマスターファイルとJOINして、名称の列に置換する必要がある。

それをやっているのがこのコードだ。ここでは、種別(各停とか急行とか)、目的駅、車両所有業者を、各々コードから名称にするため、マスターファイル(METRO_VOC_MST.TXT)と3回JOINしているのがわかるだろう。

Ajaxで送るWebパーツは、JSONではなくてHTMLコードそのもの

上記はデータの加工に関する話であったが、Webインターフェースを扱う部分にも特徴が表れている。

動作デモを見てきてもらえばわかるが、駅を選択する<select>タグの中身はAjaxで書いている。大抵は、Webサーバーから<option>タグに渡す名称と値をJSONなりXMLなりで受け取り、項目の数だけdocument.createElementをforループで回すことだろう。

しかし、サーバーサイドがシェルスクリプトならではの技で、<option>タグHTMLそのものをサーバー側で生成し、<select>エレメントのinnerHTMLにゴッソリ流し込むというやり方を使っている。

まず、流し込まれるHTMLテンプレート「TEMPLATE.HTML/MAIN.HTML」を見てもらいたい。中に次のような記述の箇所がある。

  :
<td>
<select id="from_snum" name="from_snum" disabled="disabled" onchange="get_locinfo()">
<!-- FROM_SELECT_BOX -->
<option value="-">選んでください</option>
<!-- FROM_SNUM_LIST
<option value="%1">%1 : %2線-%3駅</option>
FROM_SNUM_LIST -->
<!-- FROM_SELECT_BOX -->
</select>
</td>
:

このHTMLファイルは当然サーバー上に置かれており、次のシェルスクリプト「CGI/GETSNUM_HTMLPART.AJAX.CGI」でこれを利用している。その一部を抜粋する。

# --- 部分HTMLのテンプレート抽出 -------------------------------------
cat "$Homedir/TEMPLATE.HTML/MAIN.HTML" |
sed -n '/FROM_SELECT_BOX/,/FROM_SELECT_BOX/p' > $Tmp-htmltmpl

# --- HTML本体を出力 -------------------------------------------------
cat "$Homedir/DATA/SNUM2RWSN_MST.TXT" |
# 1:駅ナンバー(sorted) 2:路線コード 3:路線名 4:路線駅コード
# 5:駅名 6:方面コード(方面駅でない場合は"-")
awk '{print substr($1,1,1),$0}' |
sort -k1f,1 -k2,2 |
awk '{print $2,$4,$6}' |
uniq |
# 1:駅ナンバー(sorted) 2:路線名 3:駅名 #
grep -i "^$rwletter" | # ←関係ある路線だけに絞り込んでいる
mojihame -lFROM_SNUM_LIST $Tmp-htmltmpl -

まず前述のHTMLのうち<option>タグの部分(FROM_SELECT_BOXというコメントで囲まれた区間)をsedで抽出している。その後、駅名マスターファイル(SNUM2RWSN_MST.TXT)の中に書いてある、(1)駅ナンバー、(2)路線名、(3)駅名のみをAWKなどで取り出し、mojihameというコマンドに流している。

ここで呼び出しているmojihameというは、やはりシェルスクリプトで書かれている自作コマンドなのだが、標準出力から与えられた行数だけ、先程抽出したテンプレートの<option>タグの行を複製するという処理を行っている。<option>タグの箇所には"%1"~"%3"というマクロ文字があるが、これらが標準入力から渡ってきた各列の文字列に置換される。これによって、

 <!-- FROM_SELECT_BOX -->
<option value="-">選んでください</option>
<option value="C01">C01 : 千代田線-代々木上原駅</option>
<option value="C02">C02 : 千代田線-代々木公園駅</option>
<option value="C03">C03 : 千代田線-明治神宮前〈原宿〉駅</option>
:
<option value="Z14">Z14 : 半蔵門線-押上〈スカイツリー前〉駅</option>
<!-- FROM_SELECT_BOX -->

というテキストが生成されるのだ。あとは、先程言ったようにこれをAjaxブラウザーに渡して、innerHTMLでごっそりハメ込んでもらえば完成。

シェルスリプトなんて非実用的でしょ?

実はこのプログラムは、そんな先入観を吹っ飛ばすべくして作った。

シェルスクリプトのポータビリティーは実は高い!

なにせこのプログラムは、curlコマンドとWebサーバー(Apache)以外は全てPOSIXの範囲で作っている。LAMPという言葉があるが、つまりMとPの部分は無し!だからLとAのある環境ならどこでも動くということだ。そしてコンパイルも不要、POSIXの範囲だからBash依存やGNU依存なども無い。さらに言うと、LとAの部分の実装は問わないので、Lの代わりはFreeBSDでも、Solarisでも構わないし、Aの代わりにnginxなどでも構わない。シェルスクリプトは高いポータビリティーを持つ、ということだ。

シェルスクリプトだって短期間開発ができる

また、「できるのはわかるけど、フレームワーク無しに一から作ってたら時間かかるだろうが」と思うかもしれないが、それも誤りだ。このコンテスト募集開始日(2014/09/12)から、本ソフトの公開日(2014/09/16)までたった4日であることに注目すべきだ。しかも実際は1日で書いている(信じないかもしれないが)。公開日が16日なのは、ソースコードの公開が利用規約に違反しないという公式回答が15日にあったので、「それなら作るか!」と作ったのが始まりだったのだ。1日、それが信じられなくても4日で作ったというこの事実が、シェルスクリプトは短期開発でも「使える」ということを証明しているだろう。

 

見直した? 見直したら、そんなシェルスクリプトでとあるアプリを開発したとうネタを収録した薄い本


コミケ4日目は、はてブで本を買おう - りっちけんきゅうじょのにっき

も、よろしくね。(ちゃっかり宣伝)

 

 

←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。

*1:curlコマンド以外

コミケ4日目は、はてブで本を買おう

どうもこんにちは。毎度の季節でございました。夏コミで薄い本を頒布しました。 スペースは、8/17(日) 3日目 西き36b「松浦リッチ研究所」でした。……と、「検討!目論見委員会Z」さんのブログと同じことを書いてますが。(過去形で)

コミケ4日目は、『恐怖の』ショッピングカートが暗躍する日!

f:id:richmikan:20140818124430j:plain

Webサービス屋がよってたかって作る技術マガジン

ななかInside PRESS vol.5

2014年8月17日 発行(コミケ86 3日目)

頒布価格:1200円

←表紙
コールドフォイル印刷で女神さまがキラキラ輝く特別仕様

各記事紹介発行元サークルページ

現在、カゴに冊入っています

(Safariをお使いの方はコチラで注文)

コミケ会場で「明日になるとはてブで買えるんですか!? じゃあ明日買います」とおっしゃっていたお客様、お待たせしましたー。手前に設置したカゴに入れるボタンで注文数を決めていただき、ブラウザー底部の「レジへ進む」ボタンをおしてください。

というわけで、この雑誌で特集した記事の一つにある恐怖のショッピングカート「シェルショッカー1号男」がアップを始めました。何が「恐怖」かと言えば、他人のWebページをショッピングサイトに改造し、侵略するからです。このページがそうであるように。

マジメな開発動機

名前に負けずちゃんと秘密結社らしい仕事してるわけですが、いちおうマジメな開発動機があります。それは、

  • ブログしか持たないサークルが気軽に通販を始められたらいいな
  • サークルのお友達が自分のブログで、商品を品評しながら販売手伝ってあげられたらいいな
  • 開発者が用意したテンプレだけで商品紹介が済むお店なんて、流行るワケがない
  • 商品の購買意欲はショッピングサイトで起きてるんじゃない、現場で起きてるんだ!

といった理由です。既に流行っているブログがあったら、そこに買い物カゴがあれば理想じゃないですか。購買意欲が冷めないうちに……。ショッピングサイトというのはもともと購買意欲がある人が訪れる場所であり、そこで買いたい衝動が生まれるわけではありません。そういうのに向いているのはブログでしょう。しかも商品を推している友達のブログにそのボタンあったら尚効果的。

そう考えると、ショッピングカート開発者自らが商品紹介テンプレとプログラムを実装するなんてとてもバカバカしく思えたわけです。だいたい、開発だってめんどくさいし。

じゃあ、「カゴに入れる」などのパーツのみを提供して貼ってもらえるようにすりゃいーじゃんというのがこのショッピングカートのコンセプト。で、それを悪用(笑)すると、世界中のWebサイトを自分のショッピングサイトと化して世界征服できちゃうわけです。

おのれぇSafariめぇ~

ただ、既知の問題としてSafariだとうまくいきません(自分のWebサイトを改造するのは大丈夫)。これはサードパーティーCookieという技術を使っているからなのですが、Safariはガードが固く、突破できません。(突破できる人、やり方ぷりーず)

そもそもなぜこうしてサードパーティCookieはガードされてるかというと、下図のような洗脳工作が横行しているからなのです。

f:id:richmikan:20140818135325j:plain

ショッピングサイトで商品を物色すると、その後で全く関係ないニュースサイト等に移動しても、広告欄にさっき物色した商品が表示される、という……。こういうことするからショッピングサイト嫌いなんだってば!しかも、購入済の商品まで広告で出てくるし、消耗品ならいざしらず、同じ物2個も欲しいわけないだろっ!!

なので、自前のショッピングサイト開設が手軽になって、そういうショッピングサイトが壊滅すりゃいいなと思ってます。(シェルショッカーの首領が)

ところで、はてブって……

規約上、商売してもいいんだろうか???

さすがに自社サイトをショッピングカートに改造されることを想定した条文はなさそうだ。

まぁ、怒られたら素直にやめるということで、許可を求めるな謝罪せよの精神で頑張ります。



←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。

「今どきのWeb技術トレンド、多数知れる同人雑誌」出します

どうもこんにちは。毎度の季節でございます。夏コミで薄い本を頒布します。 スペースは、8/17(日) 3日目 西き36b「松浦リッチ研究所」です。……と、「検討!目論見委員会Z」さんのブログと同じことを書いてますが。
コミケ4日目の記事もどーぞ。

女神さまといっしょに、Immutable Infrastructureのおべんきょうしたい

f:id:richmikan:20140720163152j:plain

~Webサービス屋がよってたかって作る技術マガジン~

ななかInside PRESS vol.5

2014年8月17日 コミケ86で初売り

頒布価格:1200円(本体1200円+税0%)
各記事紹介

現在、カゴに冊入っています

(8/18、こちらでも頒布を開始しました)

この本、第7開発セクションというサークルさんが発行しているのです。が、無理矢理「コラボ」ということにさせてもらって、46ページほど当研究所の記事をねじ込ませていただきました。そのうえ「ウチで売らせろー!」と、まるで当研究所の発行物であるかのような取り扱い(ヒドイ)。でも、それには1つワケがあってですね……

『侵略型』ショッピングカートでこの商品を取り扱いたくて

本誌には特集が2つあり、その片方は「(少なくとも)2クセくらいあるショッピングカートを作ったぞ」という記事です。その2クセとは、

というものです。ホラ、ここってはてなブログのはずなのに「カゴに入れる」ボタンとか「レジへ進む」ボタンとか付いてるでしょ(8/18まで使えませんけど)。そのヒミツを語っているのです。しかも、このプログラムを開発したのはシェルショッカーという悪の秘密結社で、彼らが改造と侵略行為を繰り広げるというサイドストーリー付だったりします。

しかし、いくら恐怖のショッピングカートがあるとはいえ、そこに商品がなければ本当に動くことを示すことができません。そしてデモするなら、やっぱり魅力的な商品を置かない手はありません。そこで目を付けたのが「ななかInside PRESS」なのでした。

中身も表紙も、目を付けた甲斐があるというもの

バックナンバー(これとかこれ参照)でCoreutils大全」という連載記事をやったりと、個人的に注目してました。そして読んでみると、耳にするけど良く知らない「気になる技術トレンド」が結構語られている雑誌なのです。ザッと読めば大まかに、じっくり読めばより深く、そのトレンドを知ることできてイイな、と。

さらにイイのは表紙のクォリティーですよ。こういっちゃ何ですが、中身が良くてもイラストやデザインのレベルが低いとガッカリしません? いや中身が良いほど残念でなりません。その点でこの本は満足してます。電車の中でも、職場でも安心して読めますね。しかも、vol.5は特殊な印刷によりキラキラしているらしいです(こんな感じ?)。女神さまカワイイです。

今どきのWeb系技術ノウハウも仕入れておく

もう一つの特集記事のテーマImmutable Infrastructureも興味あります。仮想マシンが普及したのをいいことに、マシンを使い捨てるというわけですか。いゃぁ時代を感じます。バージョンアップを繰り返して得体の知れない環境になって苦しむより、クリーンインストール状態の環境にヒョイヒョイ乗り換えていけるのが一つの利点だといいます。確かにウチにはmake worldしてOSのバージョンを上げてから日本語manが一部文字化けするようになってしまったFreeBSDマシンがあって悩んでたりします。そんな人こそImmutable Infrastructure、というわけですね。自力で調べてやろうとすると挫折しそうですけど、掻い摘んだ手順が書いてあるので挑戦してみようかな。

他にも、気になる記事がちらほら。本誌のキーワードを並べてみると、こんな感じです。

Immutable Infrastructure、Serverspec、Ansible、Vagrant、Docker、Cobbler、Serf、シェルスクリプトアプリ開発サードパーティCookiePayPal APIFDM式3DプリンタバランスWiiボードOpenSound ControlプロトコルAWSRoute 53、roadworker、マニ車Socket.IO、WebSocket、Engine.IO、HTTP/2クライアント・サーバー(nghttp2、Apache Traffic Server、Google Chrome Canary、Firefox Nightly Build、h2load)、SPDY

個人的には、WebSocketとかHTTP/2とか気になるなぁと。このあたりの話はもうちょっと詳しく知っておきたいです。

というわけで、今度の週末(8/17日曜)のコミケで扱いますので、その日はき-36bへぜひお越しください。ちなみに、同じ島の変態論文(き-16b)も気になっていたり……。 

追伸

第7開発セクションのみなさま、お付き合いさせていただいてありがとうございます。あと、いろいろすみません。コミケでは頑張って頒布させていただきます。m(_ _;)m 

 

←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。

「リッチなコンピューター入門」復刻

もうすぐ夏コミ。早く来い来い8/17……、いや、まだ原稿終わってないのでもうちょっと待ってもらいたく。

あのコンピューター工学同人誌が12年ぶりに復刻

f:id:richmikan:20140720163152j:plain

リッチなコンピューター入門

~脱いでもスゴいコンピューター贅肉書~

2002年8月11日 初版発行

頒布価格:500円(本体500円+税0%)

現在、カゴに冊入っています

2002年。当研究所が初めて発行した「リッチなコンピューター入門」を、2014年の夏コミ合わせで復刻します。

じつは今、自作ショッピングカートを開発してるのですが、自らデモを行うには何か商品を用意しなきゃと考えておりました。そこで、コンピューターの仕組みを一から学べる本として人気の高かった本をこの機会に復活させようと思います。

カートのデモに使うなら、コミケで売ってどーする!?

そう思いますよね?

「ショッピングカートはネット販売ツールなんだから、コミケ会場で手売りするなら使いどころがないだろう」

と。でもじつは、このショッピングカートの真価は今後の機能拡張で発揮されるのです。その真価とは、ネット通販と会場(店頭)販売の垣根を取り払うこと。

そのために、会場で売る本書には、ナゾのシリアルナンバーが添付されます。これが、どういう特典をもたらすのかは、たぶん冬コミあたりに明らかになります。

発送は8/18以降になりますが、もしよろしければぜひ予約購入してみてください。

←カゴに商品が入っている時にこのボタンを押せば、レジへ移動します。

Markdown記法で、シェルスクリプトの過去記事を投稿してみるてすと

投稿テスト。

へぇー、Markdown記法もイケるんですね!

シェルスクリプトの実力を再検証する。

この記事は、Tipsというよりはむしろシェルスクリプトの実力を見直そうよ、という内容の記事だ。コードを詳しく見ればその中にはいくつかTipsが詰まっているかもしれないが……。

それよりも、シェルスクリプトの処理速度や機能を再認識してもらえればと思う。

ネット通販によくあるアレくらい、/bin/shでだって作れるもん!

シェルスクリプトの実力を示すべく、ネット通販の注文画面なんかでよく見かける 「郵便番号から住所を補完するボタン」シェルスクリプトで実装してみた。

動作デモとソース

デモは、 こちら 。ソース一式は、 GitHub上 に置いておいた。

デモ機は さくらのクラウド」の最安プラン であり、詳細スペックはこちらに記されているとおりだ。このように、今どきのライトな部類に入るマシン上で、 約14万行(レコード)=地域名12万行+事業所名2万行 ある郵便番号データから目的のデータを検索している(デモページの一番左にあるボタンを押した場合)が……、実感できる速さはいかがなものだろうか?

ちなみに、デモページの右二つのボタンはオマケである。よそのWeb APIをサーバーサイドで叩いて外部サイトに検索してもらい、結果を表示しているだけだ。だが、結果はJSONXMLテキストで渡ってくるので、 シェルスクリプトでもJSONXMLをパースできるよ という意図を込めて設置している。

簡単な構造解説

デモを試したらソースも見てもらいたい。クライアントサイドのプログラムは何の変哲もないJavaScriptなので割愛するが、サーバーサイドのプログラムは次の3種類から構成されている。

1.郵便番号辞書作成mkzipdic_kenall.sh, mkzipdic_jigyosyo.sh

dataディレクトリーの中にあるシェルスクリプト。これは、日本郵便のサイトから、Zip圧縮されたCSV形式の郵便番号データをダウンロードしてきて、その中から必要な列(郵便番号、都道府県名、市区町村名、町名)だけを取り出して辞書データファイル(サンプル(地域名用),サンプル(事業所用))を作るというもの。

コイツはCGIではなくcronで、毎晩でも毎時間でも実行させるように仕掛けておけばいい。え、「頻繁に実行したら負荷がかかるだろ!」って?大丈夫、HEADメソッドで事前にCSVデータのタイムスタンプを見比べ、新しいものが出てなければ作らないようにしてるから心配なし。

ちなみに、CSVのパースは後述の自作コマンドで行っている。(もちろんシェルスクリプトUNIX標準コマンド製)

2.住所検索CGIzip2addr.ajax.cgi

public_htmlディレクトリーの中にあるシェルスクリプト。上記のmkzipdic.shで作成した辞書ファイルからCGI経由で指定された郵便番号に対応する住所をJSON形式にしてクライアントに返す。

ちなみにzip2addr_jsonapi.ajax.cgizip2addr_xmlapi.ajax.cgiは、先に記したとおり、よそのWeb APIに検索を任せるオマケである。

3.CSVJSONXMLパーサーparsr*.sh

commandsディレクトリーの中にあるシェルスクリプト。役割は題名のとおりだ。コイツらを通すと、CSVJSONXMLデータの欲しいところがAWKgrep等で簡単に取り出せるようになって超便利。

先に記したとおり、これらももちろんシェルスクリプトUNIX標準コマンドで作られている。

実は「速い!」「色々できる!」シェルスクリプト

この記事で結局私が訴えたいのは、この見出しに書いたことである。

シェルスクリプトなんて遅いから使えないよ

と思っているアナタ。いやいや「ちょっと待ったー!」と言いたい。

シェルスクリプトはグルー言語。シェルスクリプト自身でこなそうとせずに、コマンドを呼んでそれらに任せればいいのだ。コマンドを呼べば、シェルスクリプトはその後コマンドの終了を待っているだけ。UNIX標準コマンドたちはC言語で書かれているため、それらを駆使するシェルスクリプトなら、殆どCプログラムの速さで動くことになる。

また、データの持たせ方も工夫次第。郵便番号はたかだか14万行だから1ファイルでよかったが、もし100万行、1000万行のデータだったら……と思うかもしれない。そうなったら、例えば郵便番号の前3桁ごとにファイル分割して持つまで。頭の3桁の検索は、OSがファイルシステムのハッシュテーブルを使って高速に行ってくれるのでシェルプログラマーが自力で高速検索アルゴリズムを組む必要は、たぶんまだ無い。

シェルスクリプトは他言語みたいに豊富なライブラリーないし、大したことできないよ

と思っているアナタ。いやいや、たぶんアナタの想像以上にいろんなことできるはず。

例えばこのデモでCSVJSONXMLテキストの解析をさせているが確かにそんなことをしてくれるコマンドは無かった。だが、シェルスクリプトを使って自作した。中身(CSV用JSON用XML用)を見てもらいたい。シェルスクリプトsedAWKgreptrなど、どれも見慣れた構文やコマンドでできている。 難しいことも、簡単なことの組み合わせで実現できるのがシェルスクリプトの強み なのだ。(マイクガンカーズのUNIX哲学定理6,7あたり

「じゃあ、Webアクセスは?」……それもこのデモで示したとおり、curlを使えばOK。「メールは?」……それは/usr/sbin/sendmailを使えば大丈夫、受信ならfetchmailコマンドとか。「でも、本格的なRDB操作はさすがに無理でしょ」……いやいや、 POSIX標準コマンドでjoinってのがあって これとかsortとかAWKとか使えば、テキストファイルでも相当本格的な操作が可能。

おかげでネット通販によくあるコレだけじゃなくて、ネット通販サイトそのものを作ったりしちゃったりなんかしちゃったりして