2011年8月29日月曜日

Nessus on CentOS-6.0

Vulnerability Scanner(脆弱性検査ツール) の Nessus を使ってみた。

Nessus について

Nessus (software) - Wikipedia, the free encyclopedia」に概要が書いてある。

そのほかの特徴を、思いつくまま挙げた:

  • 商用利用の場合は有料ユーザー登録が必要(register to ProfessionalFeed
  • 商用でない場合も登録は必要(register to HomeFeed
  • バージョン 4.4 からWebインターフェースが提供されたため、クライアントソフト(NessusClient)のインストールが不要になった
  • コマンドラインインターフェース(CLI)もある
  • デフォルト「ポリシー」が4種類提供されている。これらをコピーして自分のポリシーを作成し、スキャンを実行する
  • 「プラグイン」を定期的に更新する必要がある(Nessus 4.4 Installation Guide によると普通は1日1回、場合によっては4時間に1回とのこと)

rpm をダウンロード

利用許諾のページ「Nessus Download Agreement | Tenable Network Security」から進んで、プラットフォームに合ったファイルをダウンロードする。今回の場合はRed Hat ES 6 (64 bits) / CentOS 6: Nessus-4.4.1-es6.x86_64.rpm をダウンロード。

インストールと設定

rpmでインストール。

# rpm -Uvh Nessus-4.4.1-es6.x86_64.rpm

あとは、Documentation のなかの Nessus 4.4 Installation Guide を読んで作業する(PDFファイル)。英語だが目次がきちんと整理されているので分かりやすい。

ポリシー作成とスキャンの実行

これも Documentation の Nessus 4.4 User Guide を読んで作業すれば難しくない。

以下は画面のキャプチャを適当に貼っていく。

ポリシーの編集画面

スキャン結果(Reports)

Severity が high のものが1個あった。

スキャン結果の詳細

Severity が high のものを掘り下げてみた。

スキャン結果の詳細

さらに掘り下げてみたところ、脆弱性に関する詳しい説明が表示された。

CVE-2011-3192と書いてあり、2011年8月19日に発見されたApacheの脆弱性のことだと分かる(脆弱性と対策は以下のリンク先に書いてある)。

対策を行ってから再度スキャンしてやると、当然ながらこの脆弱性はレポートから消えた。

tar コマンドの xattrs オプション

star

少し前の Linux(RedHat)では、SELinux や ACL の情報をもったファイルをアーカイブするときに star というコマンドを使うことになっていた。

ただし、このコマンドは圧縮のオプションが充実していなくて不便だった。

たとえば、gzip圧縮する場合には

$ star -H=exustar -xattr -c dir1 | gzip > dir1.tgz

のようにパイプやリダイレクトを行う必要があった(tar -z のような圧縮オプションが無いため)。

tar -xattrs

しかし、最近は tar が改良されて -xattrsオプションを使えばよくなったらしい(これで -j, -J, -z などの圧縮も使える)。

tar -xattrs の例

CentOS-6.0(Linux 2.6.32-71.29.1.el6.x86_64)にて確認。

準備
~/dir, ~/dir/file1, ~/dir/file2 を作って、テキトーにACLと拡張ファイル属性を設定。
$ cd
$ mkdir dir1 && touch dir1/file{1,2}
$ setfacl -R -m m:rwx dir1
$ setfattr -n 'user.test' -v 'test' dir1
$ setfattr -n 'user.test' -v 'test' dir1/file{1,2}
tar -xattrs でアーカイブ
$ tar --xattrs -cvzf dir1.tgz dir1
/tmp に展開して属性を確認
$ tar -xvzf dir1.tgz -C /tmp
$ getfacl -R /tmp/dir1
getfacl: Removing leading '/' from absolute path names
# file: tmp/dir1
# owner: useruuser
# group: useruuser
user::rwx
group::rwx
mask::rwx
other::r-x

# file: tmp/dir1/file2
# owner: useruuser
# group: useruuser
user::rwx
group::rw-
mask::rwx
other::r--

# file: tmp/dir1/file1
# owner: useruuser
# group: useruuser
user::rwx
group::rw-
mask::rwx
other::r--/

$ getfattr -d /tmp/dir1 /tmp/dir1/file*
getfattr: Removing leading '/' from absolute path names
# file: tmp/dir1
user.test="test"

# file: tmp/dir1/file1
user.test="test"

# file: tmp/dir1/file2
user.test="test"

…というわけで、tar -xattrs で拡張属性が保存されていることがわかった。

2011年8月23日火曜日

CentOS-6.0: semanage SELinux Command Not Found

CentOS-6.0 で semanage(SELinux用のコマンドラインツール)を使おうと思ったら command not found だった。

これはよくある話のようで、「RHEL 6: semanage SELinux Command Not Found」に回答を発見(厳密には RHEL6 向けの回答だが)。

要するに、# yum provides で欲しいファイルを指定すると、必要なパッケージがわかる。知らなかったので、覚えておきたい。

2011年8月22日月曜日

フェイス(face)を変えて見やすくしよう

Emacsのテキスト表示に関する属性、すなわちフォント、前景色、背景色、下線などをまとめたものを「フェイス」と呼ぶ。フェイスの概念は、テキストをちょっとカスタマイズしたいときなどに役に立つ。

例:SLIMEの slime-repl-inputed-output-face

下の画像は、Emacs で SLIME の REPL を使っているところ。式の評価結果「1.4142135」が赤で表示されていて見えにくいため、「フェイスを変更して見やすくしよう」という気分になる。

見えにくい部分のフェイスを調べる

問題のテキストに指定されているフェイスを調べることから始める(環境は GNU Emacs 22.3.1)。

具体的には、カーソルを「1.4142135」の所に移動して M-x eval-expression を実行。次いでミニバッファに以下の式を入力する。

(get-char-property (point) 'face)

すると、同じくミニバッファに slime-repl-inputed-output-face という文字が表示されるはず。これが見えにくい部分のフェイスの名前なので、メモしておく。

※毎回 eval-expression するよりも、「Meadow/Emacs memo: 基本的な設定」に紹介されているように、フェイスを調べるコマンドをあらかじめ init.el や .emacs に定義しておくほうが便利。

色の見本を参照して使いたい色を決める: list-colors-display

コマンド M-x list-colors-display を実行すると、以下のように色の名前("snow"、"GhostWhite"など)が表示される。この中から、新しい文字に使いたい色の名前をピックアップしておく。

フェイスを変える: customize-face

Emacsにはフェイスを変更するためのコマンド customize-face が用意されているので、これを利用する。

M-x customize-faceを実行して、目的のフェイスであるslime-repl-inputed-output-face を入力。すると、次のようなバッファができる。

下のほうにある"Foreground: Red"の所までカーソルを移動して、新しい文字の色を入力。入力に応じて右側の "sample" の文字色が変わるので、試行錯誤することもできる。

色を入力したら、上のほうにある "Save for Future Sessions" にカーソルを合わせて Enterキー を押す。これで変更が永続化、つまり .emacs や init.el に設定が書き込まれる。

確認

customize-face による設定はすぐに反映されるので、REPLのバッファに戻れば文字色の変化を確認できる。

さらに、設定ファイルを開いてみると、末尾にカスタマイズのためのコードが追加されていることがわかる。

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 )
(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(slime-repl-inputed-output-face ((((class color) (background dark)) (:foreground "IndianRed1")))))

勝手に追加されるのが気持ち悪い場合は、custom-set-faces の式を自分で作って書き込めばいい。ただし、背景の種類に応じて (background dark) の部分を調整する必要があるはず。

2011年8月20日土曜日

Tunnelblick の WARNING

Tunnelblick というのは、Mac用のOpenVPNクライアント。

今日まで気がつかなかったが、ログを見ると次のようなWARNINGが出ていた。

2011-08-20 00:13:31 WARNING: No server certificate verification method has been enabled.  See http://openvpn.net/howto.html#mitm for more info.

バージョンは *Tunnelblick: OS X 10.6.8; Tunnelblick 3.1.7 (build 2190.2413); OpenVPN 2.1.4

よくあること?

ほかの人のブログにも同じWARNINGが出てるケースが散見されるし、OpenVPNを使ううえで問題はないので、無視してよいのかもしれない。

…が、やはり気になったので調べた。

原因と解決策

実は Tunnelblick の設定ファイル( config.ovpn )が微妙に間違っていて、証明書や秘密鍵を参照できてなかった様子。念のため絶対パスで記述したらWARNINGが出なくなった。

修正前
ca ca.crt
cert client01.crt
key client01.key
修正後
ca /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/ca.crt
cert /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/client01.crt
key /Users/foo/Library/openvpn/TunnelblickVPNConfigurationClient01.tblk/Contents/Resources/client01.key

ここで、fooTunnelblickVPNConfigurationClient01 はそれぞれ Macユーザ名と Tunnelblickの設定名称なので環境に依存する。

2011年8月19日金曜日

Node.js をビルドするときの openssl-libpath

うちのMacで久しぶりにビルドしようとしたら、makeの途中でエラーが発生した(Mac OS 10.6.8 での話)。むかしは問題なかった気もするが…

解決策

makeのメッセージを確認したところ、SSL関係の共有ライブラリ(/opt/local/lib/libssl.dylib)がおかしい。そこで configure のオプションで別のパスを指定してみたら解決した。

$ git clone --depth 1 git://github.com/joyent/node.git
$ cd node
$ git checkout v0.4.11
$ ./configure --prefix=$HOME/local/node --openssl-libpath=/usr/lib/
$ make

ちなみに、オプションを表示するには configure --help と打てばOK.

$ ./configure --help
waf [command] [options]

Main commands (example: ./waf build -j4)
  abspath  : Return an absolute path.
  build    : builds the project
  clean    : removes the build files
  configure: configures the project
  dirname  : Returns the directory component of a pathname
  dist     : makes a tarball for redistributing the sources
  distcheck: checks if the sources compile (tarball from 'dist')
(略)

それと、ここで表示される "waf" って何のことだろと思ったら、Pythonでできたビルドツールらしい。Waf - Wikipedia, the free encyclopedia … 初耳でした。

2011年8月18日木曜日

JavaScriptコードの性能比較 - jsPerf

概要はこちら「JavaScriptコードのパフォーマンス比較ができるWebサービス「jsPerf」の使い方 | Web scratch」に。

とりあえず、キャピタライズ処理のためのコードを比較してみた > Upcase first character · jsPerf

※コードは「デザインとプログラムの狭間で: javascriptでキャピタライズ(一文字目を大文字にする)」のものを利用させていただいた。

使うのはとても簡単。コードだけでなく、いろいろな環境での結果を共有できるのも面白い。

あとはどういった場面で活用するか。たとえばFirebugのプロファイラでボトルネックを特定し終わって、具体的な改善方法を模索するときとか。

2011年8月16日火曜日

自然対数の底 e の計算 in Elisp

eを計算する方法はたくさんある。ここでは二つの方法を書いておく。

1. 級数

exの x=1 におけるテイラー展開を求めてやると、次のような級数表現が得られる。

e=\sum^{\inf}_{n=0}\frac{1}{n!}=1+\frac{1}{1!}+\frac{1}{2!}+\frac{1}{3!}+\cdots

この級数表現をプログラムにすると、次のようになる。

(defun e (n)
  "級数表現にもとづいてeを計算"
  (if (< n 0) 0.0
    (+ (/ 1.0 (fact n)) (e (- n 1)))))
=> e

(defun fact (n)
  "階乗を計算"
  (if (<= n 0) 1
    (* n (fact (- n 1)))))
=> fact

(e 5)
=> 2.7166666666666663

n=1 から n=20 までの実行結果。

(2.0
2.5
2.6666666666666665
2.708333333333333
2.7166666666666663
2.7180555555555554
2.7182539682539684
2.71827876984127
2.7182815255731922
2.7182818011463845
2.718281826198493
2.718281808918177
2.7182818042763013
2.7182818091495133
2.718281802164987
2.7182817951863503
2.718281799212947
2.7182818049171673
2.7182818140377822
2.7182818360880554)

プロットしてみた。

2. 一般連分数

具体的な式は、「ネイピア数の表現 - Wikipedia」の「II. 一般連分数による表現」に書いてある。これを漸化式の形で書くと、

\begin{eqnarray}\begin{array}{rcl}f_n&=&2+\frac{1}{f_{n-1}}\\f_{n-1}&=&1+\frac{1}{f_{n-2}}\\f_{n-2}&=&2+\frac{2}{f_{n-3}}\\&\vdots&\\f_0&=&n\end{array}\end{eqnarray}

1, 2, ... と増えていく部分を i で表すと、

\begin{eqnarray}f_{n-i}=\left\{\begin{array}{l}2+\frac{1}{f_{n-1}} \ \ \ \ (i=0)\\i+\frac{i}{f_{n-i-1}}\ \ \ \ (1\leq i\leq n-1)\\n \ \ \ \ (i=n)\end{array}\end{eqnarray}

さらに、 j = n - i つまり i = n - j と変換すると、

\begin{eqnarray}f_{j}=\left\{\begin{array}{l}2+\frac{1}{f_{j-1}} \ \ \ \ (j=n)\\n-j + \frac{n-j}{f_{j-1}} \ \ \ \ (1\leq j\leq n-1)\\n \ \ \ \ (j=0)\end{array}\end{eqnarray}

これをプログラムで表現すると、

(defun e (n)
  "一般連分数による表現にもとづいてeを計算"
  (labels ((f (j)
              (cond
               ((= n j) (+ 2 (/ 1.0 (f (1- j)))))
               ((zerop j) n)
               (t (+ (- n j) (/ (float (- n j)) (f (1- j))))))))
    (f n)))
=> e

(e 5)
=> 2.7184466019417477

※浮動小数点数で計算するために、一箇所だけfloat関数を使っている。

n=1 から n=20 までの実行結果。

(3.0
2.6666666666666665
2.7272727272727275
2.7169811320754715
2.7184466019417477
2.718263331760264
2.71828369389345
2.7182816576664037
2.7182818427778273
2.7182818273518743
2.718281828538486
2.718281828453728
2.7182818284593786
2.7182818284590256
2.7182818284590464
2.718281828459045
2.7182818284590455
2.7182818284590455
2.7182818284590455
2.7182818284590455)

1の方法で求めた図に重ねてプロットしてみた(赤い点)。

2011年8月11日木曜日

Scheme の set! の読み方

"set bang" つまり「セットバン」と発音する。「The Seasoned Schemer」「Scheme修行」の注に書いてあった。

「"!"を"bang"と読むのかー、へー」と思ったが、そういえばUnixスクリプトの "#!" も「シェバン」と読むからごく自然な発想だ。

2011年8月8日月曜日

スタンフォード大のオンラインクラス - Introduction to Artificial Intelligence

Paradigms of Artificial Intelligence Programming」を書いた Peter Norvig の講義を無料で受けられる、という企画を発見した。

ここ「Introduction to Artificial Intelligence - Fall 2011」に登録フォームや動画がある。

ざっと読んだところ、宿題やテストの回答を送れば採点してくれて、最後には評価メールのようなものをくれるらしい(You will receive a letter of completion from the instructors which will include information on how well you did. と書いてあった)。期間は10週間で、リアルの講義は今年の9月末、オンライン版は10月から開始予定。

ちなみに教科書は PAIP ではなく「Amazon.co.jp: Artificial Intelligence: A Modern Approach (3rd Edition) (Prentice Hall Series in Artificial Intelligence): Stuart Russell, Peter Norvig: 洋書」という本。申し訳ないが存在すら知らなかった。PAIP と内容が似ているのだろうか、Lisp を使うのだろうか…

さらにここ「Stanford University CS 221 Introduction to Artificial Intelligence」にも情報があった。前提条件として、線形代数と確率の知識が必要とのこと。

2011年8月7日日曜日

JavaでJSONのパース/シリアライズ - Gson

久しぶりにJavaの仕事。

JSONを処理するにあたってGsonというライブラリを使ったのでメモ。

Gson

そもそもGoogle社内で開発・利用していたものを、一般に公開したとのこと。

google-gson - A Java library to convert JSON to Java objects and vice-versa - Google Project Hosting から現在の最新版である google-gson-1.7.1-release.zip をダウンロードし、コンパイル&実行に必要な gson-1.7.1.jar を抽出しておく。

JSONのパース/シリアライズ

Gsonクラスをインスタンス化して、インスタンスメソッドである fromJson(), toJson() でそれぞれパース、シリアライズを行う。

JSONオブジェクトのキーがJavaの予約語と一致してしまう場合、つまり {"try":1, "class":2} のような場合、そのままではパースができないためアノテーション @SerializedName を使って対応する必要がある。

サンプルコード

Gsonを使ってパースとシリアライズを行う。パースするJSONは {"class":999} でキーにJavaの予約語"class"を含むため、@SerializedName を使ってJavaオブジェクトのフィールド_class と対応させる。

import com.google.gson.Gson;
import com.google.gson.annotations.SerializedName;

public class Test{

    // JSONに対応するクラス。フィールド1個だけ。
    private class Myobj {
        // _classフィールド
        // 対応するJSONのキーがJava予約語(class)なのでアノテーションを付ける
        @SerializedName ("class") private int _class;

        // toString()
        public String toString() {
            return "_class: " + this._class;
        }
    }

    // main
    public static void main (String[] args) {
        // JSON
        String json = "{\"class\":999}";

        // JSONをパース
        Gson gson = new Gson();
        Myobj myo = gson.fromJson(json, Myobj.class);
        System.out.println("fromJson: " + myo);

        // Javaオブジェクトをシリアライズ
        String s = gson.toJson(myo);
        System.out.println("toJson: " + s);
    }
}

コンパイル&実行結果。ちなみに環境は Mac OS X 10.6.8 (Darwin 10.8.0 x86_64)。

$ javac -classpath gson-1.7.1.jar Test.java
$ java -classpath ./:gson-1.7.1.jar Test
fromJson: _class: 999
toJson: {"class":999}

2011年8月4日木曜日

オイラー・丸山法とPythonのMatplotlib

MatplotlibはPython向けの2次元プロットライブラリ。Wikipediaの記事「Euler-Maruyama method - Wikipedia, the free encyclopedia」(確率微分方程式の数値解法「オイラー・丸山法」)の、サンプルプログラムの中で使われていたので、インストールすることになった。

以下、Mac OS 10.6.8にMatplotlibをインストールして、Wikipediaのサンプルプログラムを実行したという話。

Matplotlibのインストール

Mac OSの場合、特にMacPortsやHomebrewなどのパッケージ管理ソフトを使っているとインストールがうまくいかないことが多いらしい。というのは、Matplotlibが最新の共有ライブラリにリンクされずに、パッケージ管理ソフトであらかじめ導入されていた別の共有ライブラリにリンクされる、といった現象が起こりやすいから。開発者の人も認識しているようで、README.osxというファイルに"Building mpl on OSX has proven to be a nightmare because of all the different types of zlib, png and freetype that may be on your system."と書いてあった(まるでナイトメアらしい)。

Mac OS X 10.6.8 (Darwin 10.8.0 x86_64) では、次の手順でインストールができた。

1. PythonとNumPyを確認

前提条件として、Python 2.5以上と、NumPyモジュール(version 1.1以上)が必要とのこと。これは以下のコマンドで確認できる。

$ python --version
Python 2.6.1
$ python -c "import numpy;print numpy.__version__"
1.2.1

自分で入れたのか最初から入っていたのか記憶が無いが、とりあえず自分の場合はすでに必要なものがインストールされていた。

2. githubからMatplotlibを取得
$ git clone https://github.com/matplotlib/matplotlib.git
3. make.osxの一部を書きかえる
$ cd matplotlib
$ vi make.osx
$ git diff make.osx
diff --git a/make.osx b/make.osx
index 4639eac..8dc60c7 100644
--- a/make.osx
+++ b/make.osx
@@ -3,6 +3,7 @@
 # make -f make.osx PREFIX=/Users/jdhunter/dev PYVERSION=2.6 fetch deps mpl_install
 # (see README.osx for more details)
 
+PREFIX=/usr/local
 MPLVERSION=1.1.0
 PYVERSION=2.6
 PYTHON=python${PYVERSION}
@@ -16,8 +17,8 @@ ARCH_FLAGS=-arch i386 -arch x86_64
 # but the download URLs are subject to change.
 
 ZLIBVERSION=1.2.5
-PNGVERSION=1.5.1
-FREETYPEVERSION=2.4.4
+PNGVERSION=1.5.4
+FREETYPEVERSION=2.4.6

変更点は3つ。第一に、共有ライブラリのインストールパスを"/usr/local/lib"にしたいので、PREFIX=/usr/local を追加。それから、libpng と freetype のバージョンを現時点で最新の番号にした。

4. makeする
$ make -f make.osx fetch deps mpl_install_std

これを実行すると、fetch, deps, mpl_install_stdという3つのターゲットが処理される。fetchがzlib等のライブラリのソースをダウンロードしてきて、depsがライブラリのコンパイルとインストールをして、最後にmpl_install_stdがMatplotlib自身のコンパイルとインストールを行う流れ。

完了したら、/usr/local/lib/Library/Python/2.6/site-packages/matplotlib を確認してみる。

$ ls -t1 /usr/local/lib/
libz.1.2.5.dylib
libz.1.dylib
(略)

$ ls -t1 /Library/Python/2.6/site-packages/matplotlib
mlab.pyc
mpl.pycf
offsetbox.pyc
(略)

$ otool -L /Library/Python/2.6/site-packages/matplotlib/_png.so
/Library/Python/2.6/site-packages/matplotlib/_png.so:
 /usr/local/lib/libpng15.15.dylib (compatibility version 20.0.0, current version 20.0.0)
 /usr/local/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
 /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 7.9.0)
 /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

ポイントは(1)共有ライブラリができていて、(2)matplotlibのモジュールができていて、(3)モジュール内の共有ライブラリが(1)の共有ライブラリに依存していることの3つ。

オイラー・丸山法

常微分方程式の世界における「オイラー法」に対応するのが「オイラー・丸山法」らしい。「丸山」のフルネームは丸山儀四郎。

Euler-Maruyama method - Wikipedia, the free encyclopedia のExample code(Python)をそのままコピー&実行するとグラフができる。

コードでrandomとか使ってるからあたり前だけど、「実行する度に結果が変わってOK」という考えが新鮮。これまで確定的な微分方程式の数値計算しか扱ったことが無かったので変な感じがする。

ざっと検索したところ、普通のプログラミング環境ではなくエクセルを使って計算する人もいる(そういう方向性の本が出版されている)。

Mac OS で XZ形式アーカイブを使う

今日まで知らなかったが、Mac OS標準のコマンドでは "tar xJf *.tar.xz" ができない。

大抵は gzip か bzip2 を使えば済む話だが、どうしても xz しか選択肢が無い状況なら XZ utils と GNUのtarをインストールするとよい(詳しいことは「Mac で XZ 形式を圧縮・解凍したいときの備忘録 - takkan_mのNo planな日常」に書いてあった)。

あとどうでもいいが tar のオプションは人によって揺らぐ。Jxf だったり xJf だったり -Jxf だったり… 自分の場合は xc が必ず最初に来る。コマンドを打つとき、開く(x)か閉じる(c)かが最初に頭の中で決まるから。

2011年8月3日水曜日

GoogleのBloggerに関連記事を表示する(brps - gas.js)

クリボウの Blogger Tips: Blogger で「関連記事」リストを表示する 2 つの方法 を参照して「3行コピペでできる方法」を今日試したのだが、期待どおりに動作しなかった。具体的には、関連記事のリストが表示されるべき位置に「キーを取得してください」という旨のエラーメッセージが表示されてしまった(英語だった)。

問題のJavaScriptを提供しているbrpsプロジェクトページ brps - Blogger Related Posts Service - Google Project Hosting を調べたら、「ClientGasJs」のページに違う方法が書いてあった。BRPSデータベースを使う方式から、Google AJAX Search APIを使う方式に変えた、ということらしい。

こちらの方法はうまく動作したので、メモしておく。

1. Blogger 管理画面「レイアウト > HTML の編集」ページを開く
「ウィジェットのテンプレートを展開」にチェックを入れる
2. 関連記事を表示したい場所に <div id='gas-results'/> 等を追加
  <b:if cond='data:blog.pageType == &quot;item&quot;'>
    <div>
      <h3>Related Posts</h3>
      <div id='gas-results'/>
    </div>
  </b:if>

見出しに相当するh3の部分は、利用しているテンプレートに依存する(h2h4を使うほうが適切な場合もあるだろう)。<b:if>...</b:if>で囲んでいるのは、一つの記事だけが表示される場合に限り関連記事を表示するため。トップページやアーカイブページのように複数記事が表示される場合、今回の方法はうまく動作しない(1番上にある記事しか関連記事が表示されない)。

3. </body>の前あたりにJavaScriptを追加
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'/>
  <script>
window.brps_gas = {
//  remove_tags: ['unwanted_tag1', 'unwanted_tag2'],
//  tag_selector: 'a[rel=tag]',
  limit: 5,
//  add_sites: ['secondblog.blogspot.com', 'thirdblog.blogspot.com'],
  remove_string_regexp: /^.*?: /,
  exclude_url_regexp: /(\/search\/label\/|(archive\.html|blog\.example\.com\/|\.blogspot\.com\/)$)/,
  html_loading: '<span>Loading...</span>',
  html_no_results: '<span>Found no results.</span>'
  };
  </script>
  <script src='http://brps.appspot.com/gas.js'/>
</b:if>

jQueryをすでに利用している場合、<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js'/>は必要ない。動作を調整するためにremove_tags, tag_selector, limit等のオプションを指定できるので、状況に合わせて調整する。自分の場合は不要だったので//でコメントアウトしたが、

  • 関連記事を洗い出すときに無視して欲しいラベル(tag)があれば、remove_tagsの所に列挙する
  • ラベル(tag)のhtmlコードをカスタマイズしているのであれば、tag_selectorの所で変更する
  • 複数のドメインでブログを書いているのであれば、add_sitesの所に列挙する。

以上の操作を行ってレイアウトを保存すればhtmlに反映される。あとは必要に応じてCSSを調整すればOK。

2011年8月2日火曜日

コマンドを手軽にマルチプロセス実行 GNU Parallel

GNU Parallelというプログラムを今さら知ったのでメモしておく。これは、複数のプログラムを並行して実行したいときに便利。

インストール

GNU Parallelのダウンロードページから最新版の parallel-20110722.tar.bz2 をダウンロードし、configure, make, make install する。

$ wget ftp://ftp.gnu.org/gnu/parallel/parallel-20110722.tar.bz2
$ tar xvjf parallel-20110722.tar.bz2
$ cd parallel-20110722
$ ./configure
$ make
$ sudo make install

ちなみに環境は Darwin 10.8.0 x86_64。

試してみる

とりあえずPerlで簡単なプログラムを作って試す。

print_argv0.pl
#!/usr/bin/perl
sleep(1);
print "$ARGV[0]\n";
exit;
1秒間スリープして引数を表示するだけのもの。これにlsの結果を入力する処理を、prallelコマンド経由で実行してみる。
同時に実行するジョブ数 = 20 で実行した場合(-jオプション)
$ time ls|parallel -j 20 ./print_argv0.pl {}
COPYING
Makefile
Makefile.am
Makefile.in
NEWS
README
aclocal.m4
config.h
config.h.in
config.log
config.status
configure
configure.ac
install-sh
missing
print_argv0.pl
src
stamp-h1

real 0m1.396s
user 0m0.229s
sys 0m0.259s
1.396s で終了したので、確かに同時に実行されている様子。lsの結果が18行なので順番に実行すれば18秒はかかってしまうはず。
ジョブ数 = 1 で実行した場合
$ time ls|parallel -j 1 ./print_argv0.pl {}
COPYING
Makefile
Makefile.am
Makefile.in
NEWS
README
aclocal.m4
config.h
config.h.in
config.log
config.status
configure
configure.ac
install-sh
missing
print_argv0.pl
src
stamp-h1

real 0m18.517s
user 0m0.231s
sys 0m0.243s
19.517s かかった。

プロセス

ついでにプロセスの状態を調べるため、ジョブの数を3にして parallel をバックグラウンド実行した後、psコマンドを打ってみた。

$ time ls|parallel -j 3 ./print_argv0.pl {} &
[1] 5140
$ ps axl
  UID   PID  PPID CPU PRI NI      VSZ    RSS WCHAN  STAT   TT       TIME COMMAND
(略)
  501  5142  5140   0  29  0  2443672   8584 -      S      p0    0:00.18 /usr/bin/perl -w /usr/local/bin/parallel -j 3 ./print_argv0.pl {}
  501  5172  5142   0  30  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl Makefile.in
  501  5173  5142   0  30  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl NEWS
  501  5174  5142   0  31  0  2437344   1048 -      S      p0    0:00.01 /usr/bin/perl ./print_argv0.pl README
(略)

parallel自体もperlで書かれており、/usr/bin/perl -w により実行されている(プロセスID 5142)。中ではforkしているらしく、子プロセスが3つ生成されている(5172, 5173, 5174)。