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

Rich Lab. Blog

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

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

UNIX

投稿テスト。

へぇー、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とか使えば、テキストファイルでも相当本格的な操作が可能。

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