Ubuntu Server 11.04 での desktop 環境における日本語使用のための作業メモ

さきほどのエントリで VNC が整ったら,次に使えるようにしておきたいのが日本語入力.

これがせっかく入った GUI ですがそれだけで環境整えようとしてもなんか上手くいきません.

System > Administration > Language Support や System > Preferences > Keyboard Input Method から色々やってもあんまり嬉しくなれません.何故か.

そこで,とりあえず iBus で mozc (LinuxGoogle 日本語入力を再現したもの) を使えるようになったまでの経緯をば.

まず System > Administration > Language Support で Japanese をインストールします.で,iBus (という Input Method) を使うようにします.

ここで再起動か再ログインが必要だったかもしれません… よく覚えてません.

その後,何故か iBus + Anthy (mozc じゃない別の IME) が上手く使えません.意味がよく分かりません.

てことで mozc をダメ元で調べつつインストールしてみたらあら何故か動くわ,という状況.

インストールは

% sudo aptitude install ibus-mozc mozc-utils-gui ibus-qt4

で多分おk.

で System > Preferences > Keyboard Input Method を選択すると「Keyboard Input Method が起動してません.起動しますか?」と英語で聞かれるので yes で.次の「もし IBus 起動してなかったらもっかいやってね」というダイアログも OK で大丈夫.

あとは Ctrl + Space とかもろもろのキーで日本語入力の ON/OFF が切り替えられます.

で,自分は Ctrl + Space は Emacs で使うので,Ctrl + Shift + Space に変更しました.というのも,英字配列にしているため Zenkaku/Hankaku キーが無いので…

Ubuntu Server 11.04 での VNC 環境構築と設定

Ubuntu は英語のものです.日本語使用のための作業は別として,VNC 環境の整え方メモ.

% sudo aptitude install vnc4server
% sudo aptitude install ubuntu-desktop

その後

~/.vnc/xstartup

の末尾に

exec gnome-session &

を追加.そして

% vncserver :1 # 単純に起動

これだけで動きます. :1 は Display ID とかなんとか.とりあえず :1 にでもしておけばおk.終了は

% vncserver -kill :1 # 終了

これだけ.

% vncserver :1 -geometry 1280x1024 -depth 24 # 画面サイズと色深度を指定して起動

これで画面大きくしたり色深度変えたりして起動できます.

あとは適当な VNC client で xxx.yyy.zzz.www:1 などに繋いでやる.ここの :1 はさっきのと合わせる.

余談というか個人の感想ですがシンプルで使いやすい client は RealVNC です.

Apache2, CGI を各ユーザのディレクトリで実行可能にする設定

さくら VPS 上の Ubuntu Server 10.10 で動く Apache2 (Ubuntu) での,CGI に関する設定メモ.

Apache2 をインストールして,ユーザごとに公開出来るディレクトリを保持してる状況まで進んでること前提.つまり

% sudo aptitude install apache2
% sudo a2enmod userdir

して

/etc/apache2/mods-available/userdir.conf

<IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root

        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit Indexes
                Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
                <Limit GET POST OPTIONS>
                        Order allow,deny
                        Allow from all
                </Limit>
                <LimitExcept GET POST OPTIONS>
                        Order deny,allow
                        Deny from all
                </LimitExcept>
        </Directory>
</IfModule>

的な設定をしてある状態.public_html という名前なんかはサーバ管理者それぞれの人によりけりだと思います.

あと当然 Perl なんかのインストールも済んでるものとします.

で,デフォルトのままでは,

/usr/lib/cgi-bin/

ディレクトリに設置したファイルしか CGI として動かせません.原因は先ほど示した Options ディレクティブに ExecCGI が無いためです.ExecCGI が指定されてないところでは CGI は動かせないのです.

てことでさっきの userdir.conf ファイルにあった Options に ExecCGI を追加します.

<IfModule mod_userdir.c>
        UserDir public_html
        UserDir disabled root

        <Directory /home/*/public_html>
                AllowOverride FileInfo AuthConfig Limit Indexes
                Options ExecCGI MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec # この行が変化
                <Limit GET POST OPTIONS>
                        Order allow,deny
                        Allow from all
                </Limit>
                <LimitExcept GET POST OPTIONS>
                        Order deny,allow
                        Deny from all
                </LimitExcept>
        </Directory>
</IfModule>

こういう感じに.

あと,CGI と認識する拡張子の設定も必要です.

/etc/apache2/mods-available/mime.conf

にある

#AddHandler cgi-script .cgi

という行を

AddHandler cgi-script .cgi .pl .rb .py

とでもしてやりましょう.要するにコメントアウトを外して,.cgi という拡張子を CGI として認識させるわけです.ついでに PerlRubyPython のよくある拡張子も追加しましょう.

これで後は

% sudo /etc/init.d/apache2 restart

で再起動してやれば OK.後はパーミッションの設定や PerlRubyインタプリタへのパスを間違えないように,という初歩的なことに気を付けて CGI を試しましょう.

以上ですが,Apache のことはまだまだ分からないことが多いので何か勘違いしてるかもしれません.参考にする場合は信じ切らないように.

参考サイト

あと Twitter で色々.詳しくは以下を.
Togetter - 「Ubuntu Server 10.10, Apache2, CGI 設定」

Apache2, Name-based Virtual Hosts 設定

さくら VPS 上の Ubuntu Server 10.10 で動く Apache2 (Ubuntu) での Name-based Virtual Hosts 実現のための設定メモ.

現在,VPS に与えられた 1 つの固定 IP アドレスにて,Apache2 を用いて Web サーバを運用しているのだが,アクセスする際のドメイン名によって表示される場所を変更したい.要するに何が出来れば満足かと言うと,http://unk1.com/ でアクセスしたときは例えば /home/unk1/www/ ディレクトリが,http://unk2.net/ でアクセスしたときは例えば /home/unk2/www/unk/ ディレクトリが表示されること.

これが Virtual Hosts なる技術で実現可能らしい.なんかすごい.Apache すごい.

参考サイト

で,そのために書き換えるべきファイルと,書き換え方と,Apache2 の再起動の仕方は以下の通り.

/etc/apache2/sites-available/default

このファイルを

<VirtualHost *:80>
	ServerName unk1.com
	DocumentRoot /home/unk1/www/
	...
	<Directory /home/unk1/www/>
		...
	</Directory>
	...
</VirtualHost>

<VirtualHost *:80>
	ServerName unk2.net
	DocumentRoot /home/unk2/www/unk/
	...
	<Directory /home/unk2/www/unk/>
		...
	</Directory>
	...
</VirtualHost>

こういう感じに変更する.多分デフォルトでは VirtualHost セクションが 1 つしかないのでコピペして増やしてやる.そして

% sudo /etc/init.d/apache2 restart

これで再起動完了.必要だった要件が満たされる.

唯一気をつける点と言えば,UbuntuApache は設定ファイルが分割されてることか.例えば今回弄った default ってのは普通は httpd.conf ってファイルで,他にも設定出来る項目がある.参考サイトの 1 行目にある

NameVirtualHost *:80

とか.これは UbuntuApache では

/etc/apache2/ports.conf

に書いてある.よって default の方では書いてはいけない (書くと再起動時に警告が出る).

以上ですが,Apache のことはまだまだ分からないことが多いので何か勘違いしてるかもしれません.参考にする場合は信じ切らないように.

inject の罠

Problem 1 - Project Euler

1000 未満の 3 または 5 の倍数を足し込む問題.ここで早速以前習得した inject を使ってみる.

p (1...1000).inject(0) { |s, i|
  if i % 3 == 0 || i % 5 == 0 then s += i end
}

実行すれば分かるがエラーになる.

p (1...1000).inject(0) { |s, i|
  if i % 3 == 0 || i % 5 == 0 then s += i end
  s
}

正しくはこう.

どういうことかと言うと,恐らく inject に渡したクロージャは毎回第 1 引数 (ここでは s) にその評価された値 (つまり戻り値.Ruby では最後に評価した値も戻り値扱いになる.) を代入する.で,前者の書き方では 3 または 5 の倍数で無いときには何も評価されない (nil が返る).よって inject のループの 1 回目のステップ終了時に s には nil が代入される.そこで nil += 3 が実行される段階においてエラーが起こる.

よってこれを解決するには毎回 s をきちんと評価すれば良い.よって最後に s とだけ書いておく.

現時点の私の直感では,この s は明らかに余分である.inject の仕様を回避するための処置である.何かこの s を書かなくて良い方法 (inject 以外のもっと適切な名前のメソッド) があれば知りたい.

強制的に width で改行させる

<span style="word-break:break-all;">

ただし IE8 と Chrome (ver 9.0) でのみ有効.Firefox (Ver 3.6) だと反映されない.

参考サイト

海の向こうの人達の感性は,優先度が「単語の途中で改行 > 矩形内に文字が収まる」なのかな?

縛り FizzBuzz

if, switch, 三項演算子を使わず,更に剰余演算子も使わないでやる FizzBuzz

#include <iostream>

using namespace std;

//0 : number, 1 : Fizz, 2 : Buzz, 3 : FizzBuzz
int function_index_table[15] = {0, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 0, 0, 3};
int next_index[15] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0};

void print_number(int x)
{
	cout << x << " ";
}

void print_fizz(int x)
{
	cout << "Fizz ";
}

void print_buzz(int x)
{
	cout << "Buzz ";
}

void print_fizzbuzz(int x)
{
	cout << "FizzBuzz ";
}

typedef void (*print_function_t)(int);
print_function_t print_functions[4] = { print_number, print_fizz, print_buzz, print_fizzbuzz };

int main()
{
	for (int i = 1, index = 0; i <= 100; ++i) {
		(*print_functions[function_index_table[index]])(i);
		index = next_index[index];
	}
	cout << endl;
}