LXC のウェブインターフェイス「LXC Web Panel」を使う

LXC Web Panel を去年の10月くらいにインストールしたのですが、早速忘れかけていたので覚え書きしておきます。

LXC Web Panel は AWS の EC2 のように WWW ブラウザから LXC コンテナを制御できるインターフェイスです。英語ですが、ごちゃごちゃとしておらずシンプルで使いやすいものになっています。

インストール

Github のページからインストールスクリプトをダウンロードして bash に食わせるだけで OK です。

wget http://lxc-webpanel.github.io/tools/install.sh -O - | bash

Python の Flask と Bootstrap で書かれているようです。もしかすると python-dev パッケージが必要かも。公式ページのインストールマニュアルを参考にしてください。

FAQ に

Can i use LXC Web Panel on Debian?

  • Nope, sorry… It doesn’t work :(

と書いてありましたが、さくらの VPS 上に作ってる Debian サーバにもインストールできました。しかし、公式サポートはあくまでも Ubuntu のようですので、自己責任で。

使う

インストールが成功すると 5000 番ポートでリスンします。WWW ブラウザで開きます。

firefox http://example.com:5000/

ログイン画面が出てきます。ユーザー名「admin」、パスワード「admin」で入れます。ログインできたら、http://example.com:5000/lwp/users でパスワードを変更しておきましょう。

lxc-web-panel

あとは見てのとおりです。必要な時にスマートにインスタンスを作ったり動かしたりできるので、いろいろとはかどりますね!

このウェブインターフェイス以前の問題ですが、ホストが Debian の場合、LXC の設定ファイルをちょっと工夫してあげなければならないので、新しいコンテナを作成する時にはシェルからコマンドを叩いているのが現実ですが、個人ユースでももっともっと VM を使うことが一般化してきたら、設定の煩雑さも解消していくと思われます。(他力本願)

ユーザごとにリソースを切り分けたりできるようになると、EC2 のようなサービスも個人でできそうですね!

参考リンク

書いた後で気付きましたが、Qiita でもっとスマートにまとめている方がいらっしゃいました。

シェルスクリプトでCGIチャットを書いてみました。

CGIは、標準入出力と環境変数を用いて動的コンテンツを生成する仕組みなので、これらを扱うことができるプログラムだったら記述言語は問いません。CGIと言えば「CGI/Perl」の組み合わせだけが突出して有名ですが、CGI/Cだって世の中にはたくさんあります。 さらに極端な事を言えば、CGI/awkだってCGI/shだって不可能ではありません。

ただし、CGI/shといったものは少なくとも私の知る限りでは、現在推奨はされていません。 Webインタフェイスとして動作するためのセキュリティを高めることに対する煩雑さであったり、大量のリクエストを効率的に捌くための本質的な性能であったり様々でしょうが、わざわざシェルスクリプトを引っ張り出してこなくても、Perl や Ruby、Python と言った気の利いた高級言語が使える環境が整っていることがほとんどでしょう。

じゃあ何故 CGI 用途にシェルスクリプトを使うかっていうと、限定された趣味の世界で、趣味目的で書く、というところが現実的なんじゃないかなって思っています。また、「(高級言語を使わなくても)シェルスクリプトだっていろいろ出来るよ!」という気持ちもあるかもしれません。(PQI Air Card のようなめちゃくちゃ小さい Linux システムにもシェルは搭載されているので、CGI/sh で簡単なウィキシステムを書いて遊んでみたりしました。)

bash.CGI

CGI として動作させるために重要なのが、リクエストの解析です。必要なものは環境変数に詰まっていますし、POST送信の内容は標準入力を読めば自分で何とでも出来ますが、シンプルかつしっかり動くbash.CGIというコードのサンプルがあるので、それをモジュールとして使いたいと思います。このコードは、CGI/Perl における CGI.pm みたいなもので、GETによるURLに付随してくるパラメータやPOST送信されたデータをシェル変数に置き換えてくれるので、いろいろ捗ります。

cgi_get_POST_vars()cgi_decodevar()cgi_getvars() の3つの関数定義と、呼び出しの大元である cgi_getvars BOTH ALL コマンドを貼っつけたスクリプトファイルを bashcgi.sh として保存しておきます。

bootstrap

最近のナウいユーザインタフェイスをちゃっちゃか実現するために Twitter の bootstrap を使っています。今回はサーバーのルートに /css や /js といったディレクトリが展開されるよう配置しています。

shellchat

さていよいよ本題。シェルスクリプトによる CGI チャットのソースコードは次のようになりました。

#!/bin/bash

. bashcgi.sh

title='shellchat!'
logfile='./log.txt'
linenb='15'

if [ -n "$nick" -a -n "$msg" ]; then
  msg=$(echo "$msg" | sed 's/</\&lt;/g' | sed 's/\(http:\/\/[^  ]*\)/<a href=\1 target=_blank>\1<\/a>/g')
  nick=$(echo "$nick" | sed 's/</\&lt;/g')
  timestamp=$(date +"%m/%d %H:%M:%S")
  echo "<code>$nick</code> <span>$msg</span> - <span class=small>$timestamp</span><br />" >> "$logfile"
  cat<<EOF
Content-Type: text/html

<meta http-equiv="Refresh" content="0; URL=$SCRIPT_NAME?nick=$nick" />
EOF
else
  cat<<EOF
Content-Type: text/html
Pragma: no-cache
Cache-Control: no-cache

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta http-equiv="Refresh" content="40; URL=$SCRIPT_NAME?nick=$nick" />
    <link rel="stylesheet" href="/css/bootstrap.min.css">
    <script src="/js/bootstrap.min.js"></script>
    <title>$title</title>
  </head>
  <body>
    <div class="container-fluid">
      <div class="row">
        <div class="col-md-2"></div>
          <div class="col-md-8">
            <h1>$title</h1>
            <div class="well">
EOF

  [ -f "$logfile" ] && tail -n $linenb "$logfile"

  cat<<EOF
            </div>
          </div>
          <div class="col-md-2"></div>
        </div>
        <div class="row">
          <div class="col-md-2"></div>
          <form class="form-inline" action="$SCRIPT_NAME" method="post" enctype="application/x-www-form-urlencoded">
            <div class="col-md-8">
              <p class="text-center">
                <input class="form-control" type="text" name="nick" size="5" placeholder="Name" value="$nick" />
                <input class="form-control" type="text" name="msg"  size="59" placeholder="Input message here." />
                <button type="submit" class="btn btn-default">
                  <span class="glyphicon glyphicon-comment"></span>
                </button>
              </p>
            </div>
          </form>
          <div class="col-md-2"></div>
        </div>
        <div class="row">
          <div class="col-md-2"></div>
          <div class="col-md-8">
            <hr />
            <p class="text-right">
              shellchat by <a href="https://dyama.org/" target="_blank">dyama.org</a>
            </p>
          </div>
          <div class="col-md-2"></div>
        </div>
      </div>
    </div>
  </body>
</html>
EOF
fi

exit 0

全体的にどべえーっと長ったらしい HTML タグがありますが、ほとんどがデザイン部です。実際に処理しているのは数行しかありません。 冒頭で bashcgi.sh を読み込んで、シェル変数に POST 送信の内容を詰め込んでいます。変数 nick と msg があれば、ログに追記した後、ユーザにはページをリフレッシュするよう META タグを返しています。また、変数がない場合はそのままログを表示しています。

セキュリティ的にも性能としても、何もやっていない分、いろいろと問題があるのですが、一応ちゃんと動いています。

shellchat

実際に動かすと、上記のように表示されます。

艦これのSKK辞書を作ってみました。

なんだかもの凄く今更感があるのですが、角川ゲームスが提供するオンライン育成ゲーム「艦隊これくしょん」のSKK辞書を作ってみました。Githubにてホスティングしてますので、ダウンロードやFolkが自由にできます。 普段のタイピングでは使わないような旧日本海軍の艦船名(艦娘名)をはじめ、装備品やゲーム中に登場する敵キャラクターの名前などを492ワードを収録しています(現時点)。まだまだ用語を網羅しているとは言えませんので、どんどん充実していけたらと思います。

Kancolle words dictionary for SKK(Githubの公開ページ)

https://github.com/dyama/skk-dict-kancolle

収録語一覧

https://github.com/dyama/skk-dict-kancolle/blob/master/src/SKK-JISYO.kancolle

辞書はUTF-8ベースで記載されています。ご利用のシステムに合わせて変更してください。src ディレクトリ内の SKK-JISYO.kancolle が辞書ファイルですが、このファイルはメンテナンスのためにソートしていません。make を実行するとソート済みの辞書を生成します。適宜、使い易いように切ったり貼ったり変換して使っていただければと思います。 また、誤字脱字、追加した方が良さそうな単語、注釈を使った便利機能のアイディアなどがありましたら、コメントやIssueをいただけると幸いです。(もちろん、Forkしたものをプルリクされても結構です!)

OpenCASCADE6.7.0でレイトレーシングレンダリングを有効にする

OpenCASCADE 6.7.0 ではレイトレーシング方式のレンダリングをサポートしている事を前回紹介しました。今回は、実際にコーディングをして試してみたものを紹介します。

前提

レイトレーシングレンダリングが何ぞや、というのは、この記事を読んでいる方なら既にお分かりだと思いますので割愛します。OCCTにおけるレイトレーシングの設定は、AIS コンテキストでも Viewer でもなく、View に付随しています。レンダリング、つまり見た目の設定なので、当たり前と言えば当たり前ですね。これは逆に言うと、同じViewerにぶら下がっているいくつかの View は、それぞれ別のレンダリング方式を設定することができるという訳です。 また、レイトレーシングをサポートした事により、それまでの方式と区別するためにOCCTでは次のようにモードとして呼称しています。

  • Raytracing Mode レイトレーシング・モード
  • Rasterization Mode ラスタライズ・モード(従来からあるレンダリング方式)

レイトレーシングがサポートされたことによって、従来からあるラスタライズ・モードが使えなくなるわけではありません。バージョン6.7.0以前のコードも(見た目まわりに関しては)レイトレーシング・モードのサポートによって書き換えの必要はなく、そのままで従来方式のレンダリングでの表示が可能です。

使い方

では、実際にコードを見てみましょう。

void OCCViewer::initViewAppearance(bool is_raytracing, bool is_shadow, bool is_antialias, bool is_reflection)
{
    if (is_raytracing) { // Enable ray tracing mode
        view->SetRaytracingMode();
        view->EnableGLLight(Standard_True);
        is_shadow     ? view->EnableRaytracedShadows()      : view->DisableRaytracedShadows();
        is_antialias  ? view->EnableRaytracedAntialiasing() : view->DisableRaytracedAntialiasing();
        is_reflection ? view->EnableRaytracedReflections()  : view->DisableRaytracedReflections();
    }
    else { // OpenGL rasterize rennaring mode
        view->SetRasterizationMode();
    }
    // ...
}

これは私が開発しているナンチャッテCADビューアー「siren」のソースコードの一部です。レイトレーシングレンダリングを有効にするには、新たに用意されたメソッド呼び出すだけで済み、非常に簡単です。 解説しなくとも書いてあるとおりですが…一応ざっくりと紹介しておきます。

V3d_View::SetRaytracingMode() Viewをレイトレーシングモードに設定します。

V3d_View::SetRasterizationMode() Viewを従来(ラスタライズした形状をOpenGLに投げて描画する)方式に設定します。

V3d_View::EnableRaytracedShadows() / DisableRaytracedShadows() レイトレーシングによる影の表現(陰ではない)を有効・無効にします。

V3d_View::EnableRaytracedAntialiasing() / DisableRaytracedAntialiasing() レイトレーシングモードの時、アンチエイリアスをかけたレンダリングを有効・無効にします。

V3d_View::EnableRaytracedReflections() / DisableRaytracedReflections() レイトレーシングモードの時、形状の鏡面反射を有効・無効にします。反射率は AIS_Shape に関連付けされたマテリアル(材質)によって変化します。

これらのメソッドをViewの初期化時に呼んでやれば、レイトレーシングによるレンダリングを行います。すべてのオプションを有効にすると、次のように描写されます。  

occt670-raytracing-sample

球と面を配置して、材質設定を「金」にしただけですが、綺麗ですね!  

やっぱり重い

私の作業PC(NVIDIA NVS 3100M)ではお世辞でも快適とは言えないくらい動作が遅くなってしまいました。とは言うものの、リアルタイムでレイトレーシングレンダリングをしているわけですから、昔のPCに比べれば、対話的に視点を回転できるだけでもびっくりです。弟の作業PC(もっと良いグラボを積んでます)でレイトレーシングモードを有効にしたところ、少ない形状数であれば、ほぼリアルタイムでぐりぐり動いているようです。 思いっきりハードウェアパワーに依存しているところですので、レイトレーシングモードの濫用は避けるべきだと思います。MayaやMAX、Blenderといった3D CGアニメーションソフトも、作業画面とレイトレーシングが有効にできるレンダリング画面は別になっていますし、用途に合わせて使っていければいいと思います。 レイトレーシングモードに絡んで、新しく追加されたGLGSベースのシェーダーとライトについては、次の記事で紹介したいと思います。

JavaScriptによる二進数時計

以前書いたコードが出てきたので貼っておきます。今見直してみると、ちょっとムダがあるコードですね。 JavaScriptは書けません、でお茶を濁しておきましょう。

// 2010/01/08 jbClock by dyama
// for Firefox, Opera and Google Chrome

var BgColor = '#F00000';
var BaseColor = '#351309';
var ActiveColor = '#FF470F';
var Height = 8;
var Width = 16;

// 文字列を指定した桁数kになるまで頭にmを挿入する
function kt( s, k, m ){ while( s.length < k ){ s = m + s;} return s;}

function bclock()
{
    var n = new Date();
    // toString(2) ... 二進数文字列にする
    // kt で頭に文字列"0"を挿入して返す
    // 0と1の文字列だと、後でHTMLを一括置換した時に置換対象以外も
    // 置換してしまうので一時的に文字0を文字列$zに、文字1を文字列$oにする
    var h = kt(n.getHours().toString(2),5,0).replace(/0/g,'$z').replace(/1/g,'$o');
    var m = kt(n.getMinutes().toString(2),6,0).replace(/0/g,'$z').replace(/1/g,'$o');
    var s = kt(n.getSeconds().toString(2),6,0).replace(/0/g,'$z').replace(/1/g,'$o');
    // 0だった場合と1だった場合のHTMLタグを準備
    var t = '<td bgcolor="' + ActiveColor + '" height="' + Height + '" width="' + Width + '"></td>';
    var f = '<td bgcolor="' + BaseColor + '" height="' + Height + '" width="' + Width + '"></td>';
    var o = document.getElementById("area");
    // "$z$z$o$z$o" のような文字列のままタグ挿入
    var v = '<tr><td bgcolor="$a" height="' + Height + '" width="' + Width + '"></td>' + h + "</tr><tr>" + m + "</tr><tr>" + s + "</tr>";
    var a = (n.getSeconds()%2)?BgColor:BaseColor;
    // 最後に$zを0用のHTMLに、$oを1用のタグにHTML全体を一括置換
    o.innerHTML = v.replace(/\$z/g,f).replace(/\$o/g,t).replace(/\$a/,a);
    // 1秒ごとに実行する
    setTimeout("bclock()", 1000);
}

これを実行すると、次のように見えます。

OpenCASCADE 6.7.0 のアナウンス

OpenCASCADEの最新バージョン6.7.0が開発者サイトでアナウンスされています。
記事によると、6.7.0では特に visualization が強化されたようで、簡単かつ高速に高品位のレイトレーシング・レンダリングがビューで可能になったとのことです。

現行リリースの最新版である6.6.0までは、正直に言うと、お世辞でも「綺麗な見た目」は提供されていませんでした。OCCT自体、三次元幾何演算部分が中核となっているライブラリですので画面表現については後まわしになっていたのかもしれません。

結果的にCATIARhinocerosといった商用CADに、第一印象(見た目)で劣るように思われがちになっている感触がありましたが、今回の6.7.0では、商用CADにも負けない美しいビューを表現できるようになったようです。

OpenCASCADE 6.7.0 の新機能

レイトレーシングによるフォンシェーディング・鏡面反射のサンプル
レイトレーシングによるフォンシェーディング・鏡面反射のサンプル
光源と陰を正確に演算しているため、小さな溝やエッジまでよりリアルかつ自然に表現が出来ている。 光源と陰を正確に演算しているため、小さな溝やエッジまでよりリアルかつ自然に表現が出来ている。
半透明処理では、重なり合う物体同士がうまく表現できている。 半透明処理では、重なり合う物体同士がうまく表現できている。
金属表現もこのとおり。 金属表現もこのとおり。

記事をかいつまんで要約しますと、

  • phong シェーディングに対応

三角形ピクセルベースの法線補完と高度な照明モデルを使用して、高品質なシェーディングができるようになったらしいです。これまでは、近似などでごまかしながらシェーディングを行なっていたみたいですが、今回はしっかりとポイントライト(点光源)とディレクショナルライト(平行光源)を使って陰が出来るようになったことで、見た目が大幅に向上したとのことです。

  • 鏡面反射と環境マッピングの対応

レンダリング画面の品質を大きく左右する鏡面反射環境マッピングもサポートされたようです。レイトレーシングがまともに実装されて初めて実現できる機能です。完全な鏡を表現しなくとも、プラスチックや塗装された金属にうっすらと映り込む周りの風景は、より直感的に利用者にイメージを伝えることができるようになると思います。

  • アンチエイリアス処理の改善

6.6.0までは、アンチエイリアス処理を有効にすると、アンチエイリアスであるにも関わらずジャギー(物体の境界のギザギザ)が目立つようになっていました。全然美しくない上に、無駄な処理をするわけで全く使っていませんでしたが、今回の改善でまともに使えるようになった模様です。

  • 半透明オブジェクトの表現の改善

これまでは、半透明オブジェクトを重ね合わせると物体の順序がめちゃくちゃに表現されていました。これは、まともにレイトレーシングをしていなかったため、視点から、手前から順に並んでいるはずの物体の位置を上手く表現できていない事が原因です。今回、これも改善されたようで、CADでなくてはならないこの表現も上手く行きそうです。

  • OpenCLでの処理

レイトレーシングを実装するにあたり、画面の描画コストはこれまで以上に大きくなることは明白です。そのため、並列処理を行うOpenCLをサポートして描画速度の改善を図っています。

レイトレーシングを有効にするコーディング

レイトレーシングモードでの描画を有効にするには、従来のコードをほとんど書き換えることなく、簡単にできるようです。
記事では、V3d_View::SetRaytrasingMode() を実行するだけで有効にできると書いてあります。また、レイトレーシング実装に伴なって DRAW コマンドも追加されており、利用方法もソースコードレベルで示されているみたいです。

今のところの制約事項

6.7.0では、レイトレーシングに関する次のいくつかの機能がまだ制限されているとのことですが、次回以降のリリースで順次利用できるようになっていくそうです。

  • テクスチャーマッピングは今のところ未サポート、従来のテクスチャもレイトレーシングには移植されていない。
  • レイトレーシングが使えるのはポリゴン形状のみで、点や曲線はサポートされていません。(つまり、ワイヤフレームなどもレイトレーシングが使えません)ここで言うポリゴン形状とは、平面分割されたポリゴンメッシュではなく、OpenGL 描画時における面、すなわち自由曲面も含まれているものだと思います。
  • 三角形メッシュの一致問題(OpenGLと同様)。描画時におけるポリゴンメッシュ分割による幾何誤差の事だろうと思います。分割精度を上げれば実用範囲において回避できるだろうとの注釈も。
  • CPU(つまり、ソフトウェアレンダリング)とIntelのGPU(Intel HD Graphicsなど)でテストされていません。
  • また、MacOS Xでもテストされてません。ユーザがこれらの環境に関するパッチ(やレポート)を提供することを求めています。
  • レイトレーシングさせる形状は、今のところOpenGLのVBOを利用せずメインメモリ上から生成するため、メモリ使用量が多くなってます。
    ** 2倍から3倍以上のメモリ使用量になってます。2GBのVRAMで、3,000,000ポリゴン程度。

これらの事は次期リリースに期待しつつも、現状だけでも充分に表現力がアップすると思われます。

DirectXのサポート!?

また、本記事とは別にOCCTのDirectXサポートについての議論も記事になっていました。
曰く、

  • OpenGL に加えて Direct3D レンダラを搭載するのは面白そう。
  • ただ、DirectX を大規模な開発をしてサポートするなら、それなりのメリットが必要。
  • Direct3D レンダラは特定のプラットフォームでしか動かない。
  • レンダラが二つになるということは、バグも倍増されてメンテが大変になる。

とのことでした。ここでは、OCCT本体に実装するのではなく、サードパーティ製の visualization ライブラリとして開発ターゲットにするのは良い方法とも述べています。
個人的には、DirectX の需要はまるでないのですが、90年代後半から今まで培われてきた技術があることは否定しません。終焉を迎えつつある技術でも選択肢が多くなることは良いことだと思います。

Draw Test Harness 日本語 Wiki 作りました

OpenCASCADE の Draw Test Harness の(ほぼ自分用の)日本語 Wiki を立ち上げるために、以前自分の個人サイトでも利用していた UseMod Wiki を導入することにしました。

UseMode Wiki は、Perl で書かれたシンプルな Wiki システムで、煩雑な設定が少なく、依存関係も少ないので重宝していました。基本部は wiki.pl に全て詰まっており、設定ファイルも一つだけ。
見た目に凝ったり、いろんなことをしようと思えば MediaWiki なんかが良いのでしょうが、そんなに時間も割きたくない、簡単な Wiki 構文が使えればいい、程度でしたら、なかなかオススメの Wiki エンジンです。

そんな UseMod Wiki ですが、Wiki 内のユーザ登録が上手く動作しませんでした。エラー内容を調べてみると、Cookie がどうもちゃんとやり取りできていない模様。公式のヘルプを読んでいると、どうも Cookie の期限が「2013 年 9 月まで」とハードコーディングされているようで、思いがけないところでひっかかっていたようです。(しかも2009年あたりからメンテナンスもされていないみたい)

晴れてユーザ登録し、古い記事を新しい Wiki に移植している途中、今度は一部の記事テキストで、ロリポの 403 エラーが出るようになりました。まるで投稿ができない。
最初は何が原因だか分からなかったので、記事名を変更してみたり、いろいろと試行錯誤していたのですが、どうもロリポが(勝手に)ウェブアプリケーションファイアウォール(WAF)を有効にしていたようで、そこにPOST内容がひっかかっていたみたいです。
ロリポは例の乗っ取り事件を起こしてから、ディレクトリのフルパスを強引に変更したり、トップがアレだったりと、あまり良いイメージではありません。他のところだったら、「ああ、そうか、気付かなかったなー」程度で終わるんでしょうが、ロリポの場合ちょっとだけアレな気分になります。
さくらのVPSも持っているので、WordPressのDBまわりの整理ができたら、dyama.orgの参照先をロリポからさくらに切り替えようと思ってます。(なかなかWordPressを気合い入れて調べる時間がない…。)
さくらのクラウドも石狩のデータセンターが稼動し始めたころ、ちょっと不具合があったみたいですが、それ以前から利用している信頼性はやっぱり高いと思います。

WordPressと言えば、WP-Markdown というプラグインを試してみました。こちらも、「そんな高度なレイアウトや見た目を求めないから、さくさくドキュメントが書ける書式で…」という理由で入れてみたのですが、過去の非 Markdown で書いた記事の Syntax Highlight と相性が悪いみたいで、掲載しているソースコードが HTML 混在の表示になってしまいました。
ひょっとしたら設定がマズいのかもしれませんが、かえって手間がかかるかもしれないので導入を見送りました。

Markdownで記事を書き、gistにコードを貼って、記事からはそれを参照…というのも考えましたが、やっぱりバックアップや以前の記事の取り扱いを考えるとムリかなぁ…。(いや、でも引っ越しは楽そう。githubが潰れない限り!)

screenをtscreenからtmuxへ乗り換えた

普段、端末経由で作業をする際、GNU Screen ライクな tscreen を使っていました。tscreen は Screen 系の中ではマイナーな類のもので、Debian の公式リポジトリにも入っていません。自前でソースコードを取ってきてビルドして使っていました。 というのも、自分が Screen を使い始めた当初は今のようにあまり選択肢がなくて、GNU Screen 以外と言えば数えるほどもなかった気がします。

tscreen を使い始めた大きな(覚えている)理由としては、本家ではできなかった画面の縦分割をサポートしていた事でしょうか。本家のキーとも互換性が高かったのも理由の一つだったと思います。

tscreen を常駐させ、中でIRCメーラー、作業環境一式を立ち上げていましたが、cgdb などのターミナル制御をガリガリやっている一部のソフトとの相性が悪かった為、今さらながら tmux に乗り替えることにしました。

tscreen と比べて気付いたこと

画面ロック

tscreen ではスクリーンセイバーとして bsdgames の worms を表示させていました。tmux でも同じように画面ロック機能を用いて、任意のコマンドを実行できましたが、実装に差があるようです。

  • tscreen 画面ロック中もキー入力は tscreen がしっかり管理しており、任意のキーを押すだけで画面ロックが解除される。

  • ** tmux** 画面ロック中のキー入力は、スクリーンセイバーとして実行されたコマンドに移ってしまい、そのコマンドを終了させない限り、tmux はキー入力を感知しない。

worms は C-c で終了しない限り終了しないコマンドです。tscreen では任意のキーを押せば、tscreen が責任をもって worms を殺してくれますが、tmux では自分で殺す必要があるようです。 セキュリティロックさせる意味では、tmux のようにキー入力を完全に画面ロックコマンドに任せてしまう方が良い気がしますが、単にスクリーンセイバーとして使いたいだけだったら、画面ロックコマンドの使い勝手に依存しない tscreen の方が利便性は高いです。 どちらも一長一短なので、まあいいんじゃないかな、と思います。

Unicode 文字の扱い

IRC では UTF-8 のチャンネルに入っていて、最近 Twitter などで良く見る Unicode 文字を駆使したキモい顔文字なんかも表示できるようになっています。 tscreen では、意図的かどうか分かりませんが、とにかく表示しようとしてレイアウト(特に文字幅)が崩れる事がありました。tmux では、文字幅の扱いに不安がありそうな文字は全て半角の「?」で表示されているようで、レイアウトの崩れが少なくなっています。レイアウトが崩れても表示させたいもの、レイアウトが崩れてまで表示させたくないもの、いろいろあるかもしれませんが、Emacs でミニバッファを開きまくっている自分としては、tmux のほうが合っている気がしました。

# 多分、意図的にやっているわけじゃないんだろうな。curses 依存のような。
# ついでに言うと、未だに ISO-2022-JP のチャンネルで CP932 依存の半角カナを垂れ流す奴ら滅びろ。
# 往々にしてそういう発言は読めなくても困ることがないけれど。

ちなみに、tmux のほうが崩れない「気がする」程度で、崩れるタイミングではやっぱり崩れます。ただ、本来の目的であった cgdb がちゃんと表示できているから及第点は超えていますね。

ウィンドウとペインの概念

本家 GNU Screen から tmux へ乗り換えた人のブログ記事でもよく目につきますが、tscreen もウィンドウとペインの概念がなく、単にウィンドウだけです。 最初は戸惑いましたが、これも慣れれば大丈夫そうです。

デザイン比較

ガリガリとカスタマイズをした tscreen と、ほとんどまっさらな設定の tmux を比べるのはちょっとナンセンスですが、なかなかダサくなってしまいました。(tmux はこれから手を入れて行こうと思います。)

tscreen

tscreen

tmux

tmux

緑一色っておま…!

tmux のペインには、tscreen のウィンドウのタイトルバーみたいなものがないので、視覚的にどのペインがアクティブになっているか分かりづらいです。あくまでもデフォルト設定なので、カスタマイズする方法はあると思いますが。ちなみに、tscreen ではアクティブウィンドウのタイトルバーを赤く、ノンアクティブを薄い緑色で表現しています。tmux 側に立って言うと、タイトルバーがない分 1 行だけ広く使えるメリットもありますね。

tmux が使っている色が緑一色というのは、「ひょっとしてANSI 256 colorをサポートしていない端末向け…」と思ったりもしますが、このご時世、あんまりメリットがない気がします。ステータスバーのアクティブウィンドウ表示も「*」で表現していますが、背景色を変えたほうがよっぽど分かりやすいです。 かと言って、画面ダンプのモノクロ印字に耐えられるほどカラー表示にレイアウトが依存していないわけでもなさそうなので、今どき「4ビットカラー対応だぜ」っていうのもなんだか。

「最初からやっといてくれる」の感覚が、もうちょっとおせっかい気味でも良い気がしました。結局、RC ファイルをいじるなら量が減ろうが増えようが、普段使いにはあんまり関係なくなります。

その他 tmux の良いところ

他の方もたくさん書いていますが、軽い気がしたり、レイアウトがそこまで崩れなかったり、そんなに設定しなくてもそこそこ使えたり、とメリットもたくさんありそうです。

下のステータスバーには、ログイン名、ホスト名、カレントパスが常に表示されているので、bash のプロンプトは「$」だけにしても良さそうですね。tscreen でも設定をガリガリ書けば出来そうですが、地味に便利です。

時刻表示は、まあ当たり前として…あとはやはり慣れでしょうかね。

tscreen では日頃の惰性から C-a をコマンドキーにしていたのですが、bash や emacs で行頭に移動したい場合や、vim で数値をインクリメントしたい場合 C-a a とタイプしなければならず、少し手間でした。コマンドキーを変更すれば良かったんですが、慣れもあってついつい使い続けていました。 tmux のデフォルトは C-b なので、vim のバックスクロールにぶち当たりはしますが、こちらに「慣れ」を変更してもいいかもしれません。ちなみに ratpoison ではコマンドキーは C-t でした。

総評

ダサさは自分で改善できるので良いとして、全体的なメリットを考えても乗り換える理由には充分だと感じました。tscreen は、公式サイトも消えてしまっているようで、多分メンテナンスも行なわれていないと思います。代わって tmux は、今もっともナウい Screen 系ソフトらしいので、ユーザ数や開発頻度、これからの改善にも期待が持てます。

さっさと調教して慣れていきたいと思います。

オマケ

全く需要がないと思いますが、これまで使っていた tscreenrc を貼っておきます。

[perl] startup_message off autodetach on

backtick 0 5 5 sh /home/dyama/bin/stat

shelltitle “$ |shell”

caption always “%{= mW} %n %{-}%?%F%{= rW}%:%{= Gk}%? %t %=” defhstatus “%n:%t” hardstatus alwayslastline “%{= bW}%-w%{= Wk}%n:%t%{-}%+w%= $USER %0`(%m/%d %02c)”

msgwait 10

defscrollback 2000

bind r eval ‘echo “Resize Window”‘ ‘command -c resize’ bind -c resize ^] command bind -c resize j eval ‘resize +1’ ‘command -c resize’ bind -c resize k eval ‘resize -1’ ‘command -c resize’

defutf8 on encoding utf-8 utf-8 defencoding utf-8

cjkwidth on

defkanji utf-7

color

defbce “on”

do not use ‘screen-bce’

term rxvt-256color termcapinfo rxvt-256color ‘Co#256:AB=\E[48;5;%dm:AF=\E[38;5;%dm:hs:ts=\E]0;:fs=\007:ds=\E]0;\007’

idle 1800 blankerprg /home/dyama/bin/worms2

↑たしか /usr/games/worms に上手く引数を渡せなかったので

シェルスクリプトを指定しています。

[/perl]

オックスフォード白熱教室

小学生の頃に家族旅行でイギリスに行った時、母の友人がいるオックスフォード大学を訪ずれました。今でこそ世界有数の大学という事を知っていますが、子供だったので、広大な緑地帯で放し飼いされていたクジャクを追い回した記憶しかありません。
今日、仕事から帰ってきて夕食に一人鍋をしていると、テレビで「NHK オックスフォード白熱教室 第4回 数学が教える“知の限界”」が放送されていました。同大学マーカス・デュ・ソートイ教授によるカオス理論を中心にした、とっても分かりやすい内容の講義(もちろん、日本語吹き替え)で、いくつも興味深い内容のお話をやっていました。かなり一般的に楽しめる事を意識した講義だとは思いますが、難しい数式どころか、黒板すら使わずに話していて、数学が分からない自分にでも理解ができるものでした。残念ながら途中からしか見れなかったので、再放送などがあれば最初から見直してみたいと思います。

レミングの集団自殺

ある海外のドキュメンタリー番組で、レミングというネズミの一種が、4年に1度、崖から海へと一斉に飛び降りて自殺するという事が紹介されました。結局、後から番組関係者の証言によりヤラセであった事が分かったのですが、レミングの個体数が周期的に増減しているのは事実らしいです。
講義では、レミングの世代ごとの個体数をある式で表して、数学的な予測が可能な範囲と予測ができない範囲、つまりカオス状態に突入するところを分かりやすく説明しています。
ある世代の個体数を [math]N_{1}[/math] とした場合、次世代の個体数 [math]N_{2}[/math] は、次のように定義されるらしいです。

[math]N_{2} = ( N_{1} \cdot PN_{1} ) – \frac{ N_{1} \cdot PN_{1} }{T}[/math]
※ただし、[math]N_{2} \geqq 0[/math]

[math]\frac{ N_{1} \cdot PN_{1} }{T}[/math] の項が減少個体数を表し、[math]T[/math] の値が小さくなるにつれ総個体数は少なくなります。また [math]P[/math] は、ある世代と次世代に生まれた個体の総数の増加率を示す係数です。
[math]T[/math], [math]P[/math] をそれぞれ、[math]T = 10[/math], [math]P = 2[/math] とした場合、最初の世代 [math]N_{1}[/math] の値が [math]0 < N_{1} < T[/math] の時、世代を重ねるごとに収束して [math]N_{2} \fallingdotseq 5[/math] という結果に安定するらしいです。

分かりづらいので、最初の個体数が 2、 3、 8、 10 だった場合のグラフを書いてみました。

Screenshot_from_2013-10-26 11:16:45

2、3、8 のいずれの場合も、最終的には 5 に収束して安定期に入ります。8 の場合、一度減った個体数が徐々に増えていくことが分かります。[math]T[/math] と同じ値の 10 は、増えることなく絶滅してしまいました。10 以上のどのような実数を与えても絶滅します。この式での最初の世代の上限は [math]N < T_{(10)}[/math] のようです。

次に、係数を [math]P = 2.5[/math] にして、最初の個体数を 2、3、9.9 だった場合のグラフを書きました。

Screenshot_from_2013-10-26 11:40:30

2 は 2 世代後には 6 に収束します。 3 は、6 の周辺に辿りついたあと増えたり減ったりしながら、やがて振れ幅が小さくなって 6 になります。9.9 の場合は、1 世代後に極端に値が減りますが、その後は徐々に回復していき、やがて 6 に収束しました。9.9 の場合の 1 世代後以降の折れ線は、[math]N = 0.1[/math] の時と同じものになります。同様に 9.5 の場合の 1 世代以降の折れ線は、0.5 の時と同じものになります。[math]T = N_{(9.5)} + N_{(0.5)}[/math] のようです。

さて、最終的に収束する値以上の値については、[math]T[/math] を超えない限り、1 世代以降でそれ以外の値と同じ折れ線になることが分かったので、2 と 3 の場合について、[math]P[/math] の値を変えて遊んでみましょう。
次のグラフは[math]P = 3[/math]の場合です。

Screenshot_from_2013-10-26 11:55:55

半ば予想どおりですが、今度は振れ幅がかなりゆっくりと小さくなっていっているようです。1 世代おきの増減が顕著に見ることができました。ここで、[math]P[/math] の値をどんどん上げることにより、振れ幅の衰退がどんどん小さくなっていき、限りなく周期的に増減をくりかえすグラフになるのかも!という期待が出てきます。
次に[math]P = 3.5[/math]の場合です。

Screenshot_from_2013-10-26 12:04:57

いきなり期待が裏切られました。3 の場合、最初の頃の振れ幅よりも途中から大きくなっています。
さらに[math]P = 3.7[/math]の場合、

Screenshot_from_2013-10-26 12:08:37

かろうじて 1 世代おきに増減をくりかえしているものの、振れ幅の大きさがめちゃくちゃになりました。
そして[math]P = 4[/math]、

Screenshot_from_2013-10-26 12:11:15

1 世代おきにくりかえしていた増減すらなくなり、完全に予測できないグラフとなりました。

番組では、4 年に一度、周期的に個体数を極端に減らすレミング題材にして、このようなグラフを紹介していました。[math]P[/math] と最初の個体数によって、レミングの個体数に似たグラフを表現できるということです。さらに、上で試してみたとおり、この式では [math]P[/math] が 3.5 から周期性が失なわれ始め、4 になると予測不可能なめちゃくちゃな状態、つまり「カオス状態」に突入することも紹介していました。

このレミングの話の前に、重力がお互いに影響し合う惑星の軌道や、複数の磁石を用いた振り子、二重振り子の話がありました。そこで、ささいな初期状態の変化が結果的には、予測不可能なカオス状態へ突入しかねないバタフライ効果についても触れていました。

余談ですが、番組では 4 までしか触れていなかったので、「[math]P[/math] の値を上げれば上げるほど、折れ線はどんどんカオス状態になっていくんだろうなあ」という淡い期待をしてしまいましたが、実際には…

Screenshot_from_2013-10-26 12:22:56

[math]P = 5[/math]の場合、2 が 8 に収束するわ、3 が [math]T[/math] を超えていないにも関わらず、絶滅してしまうわ、グラフの折れ線的にはグラフの後の世代を予測できる非カオス状態になりましたが、これまでの考え自体を否定する結果となりました。

そもそも、そういう挙動をする式だと言ってしまえばそれまでですが、初期状態の小さな変化によって、結果が予測不可能なものになる分かりやすい例えだったと思います。