カテゴリ "プログラミング" のエントリ

VMware Labs の Onyx に Web Client 用が出ていた

ぜんぜん知らなかったのだけれど、ふと VMware PowerCLI Blog を見たら、VMware Labs の Onyx の Web Client 対応版、Onyx for Web Client のリリースの案内が出ていた。

System Requirements には vSphere Web Client 6.0 用と書いてある。6.0 の Web Client から 5.5 につなげば 5.5 でも使えそう(後方互換、あったよね?)。

Onyx というのは、vSphere Client の操作を PowerCLI や C# や vCO 用の JS などのコードにしてくれるとても便利なもので、ぼくも三年前に『vSphere Client の操作を PowerCLI のコードにしてくれる VMware の Onyx がすごく便利』というエントリを書いている。

このエントリ、いまでもちょくちょくアクセスがあるのだけれど、この末尾にこんな一文を入れていた。

vSphere 5.1 からは vSphere Client ではなくて vSphere Web Client が標準になってくるので、Onyx たんがアップデートしてくれないといずれ使えなくなる疑惑がある。

結局、従来の C# 版クライアント用の Onyx も 2014 年までは継続的にアップデートされていて、なんだかんだで vSphere 5.5 の C# 版クライアントでも使えてはいる。とはいうものの、根本的に C# 版クライアントだとできないことも多いわけで。

Web Client 用のが出てくれないとそのうち困りそうだなあと、このときからつらつら考えてはいたのだけれど、無事にリリースされてくれてよかった。安心した。


PowerShell と bash で任意のコマンドの出力の全行頭にタイムスタンプを付ける

Tera Team でログを取るときの “タイムスタンプ” オプションみたいなことを、OS のネイティブの機能でやりたいシーンがあった。一時的な人力監視とか作業の証跡とかで。

以下、Windows の場合(PowerShell)と Linux の場合(bash)のそれぞれで。

Windows の場合(PowerShell)

ワンライナでやる

こうする。

<任意のコマンド> | foreach-object {(get-date -f "[yyyy/MM/dd HH:mm:ss.ff] ") + "$_"}

コマンドによっては表示が崩れるので、その場合は Out-String -Stream を通してやるとだいたいうまくいく。

<任意のコマンド> | out-string -stream | foreach-object {(get-date -f "[yyyy/MM/dd HH:mm:ss.ff] ") + "$_"}

結果、こうなる。

PS> ping 8.8.8.8 -t | foreach-object {(get-date -f "[yyyy/MM/dd HH:mm:ss.ff] ") + "$_"}
[2015/11/02 01:04:43.31]
[2015/11/02 01:04:43.32] 8.8.8.8 に ping を送信しています 32 バイトのデータ:
[2015/11/02 01:04:43.32] 8.8.8.8 からの応答: バイト数 =32 時間 =7ms TTL=56
[2015/11/02 01:04:44.32] 8.8.8.8 からの応答: バイト数 =32 時間 =9ms TTL=56
[2015/11/02 01:04:45.32] 8.8.8.8 からの応答: バイト数 =32 時間 =4ms TTL=56
[2015/11/02 01:04:46.32] 8.8.8.8 からの応答: バイト数 =32 時間 =12ms TTL=56

関数にする

関数にする場合は、例えばこんな感じ。

function add-timestamp {
	[cmdletbinding()]
	param (
		[parameter(valuefrompipeline = $true, mandatory = $true)][psobject] $object,
		[string] $format = "[yyyy/MM/dd HH:mm:ss.ff] ",
		[switch] $trim
	)
 
	process {
		$object | foreach-object {
			if ($trim) {
				(get-date -f $format) + "$_".trimend()
			} else {
				(get-date -f $format) + "$_"
			}
		}
	}
}

-format(-f でもよい)で任意のフォーマットを指定できる。何も指定しなければデフォルト(”[yyyy/MM/dd HH:mm:ss.ff] “)。

-trim(-t でもよい)は、行末の不要な空白を削除するオプション。なにかの結果を format-table してから add-timestamp に渡すと、行バッファがあふれて折り返されて、全行間に空行が入って見えることがあるので、これを見掛け上抑止するためのもの。

使うときはこんな感じ。ワンライナの場合と同様、場合によっては out-string -stream を噛ませた方がよさそう。

<任意のコマンド> | add-timestamp
<任意のコマンド> | add-timestamp -f "<HH:mm:ss> "
<任意のコマンド> | add-timestamp -t
<任意のコマンド> | out-string -stream | add-timestamp

結果、こうなる。

PS> ping 8.8.8.8 -t | add-timestamp
[2015/11/02 01:16:18.65]
[2015/11/02 01:16:18.65] 8.8.8.8 に ping を送信しています 32 バイトのデータ:
[2015/11/02 01:16:18.66] 8.8.8.8 からの応答: バイト数 =32 時間 =4ms TTL=56
[2015/11/02 01:16:19.66] 8.8.8.8 からの応答: バイト数 =32 時間 =4ms TTL=56
[2015/11/02 01:16:20.66] 8.8.8.8 からの応答: バイト数 =32 時間 =5ms TTL=56
[2015/11/02 01:16:21.66] 8.8.8.8 からの応答: バイト数 =32 時間 =8ms TTL=56

Linux の場合(bash)

ワンライナでやる

こうする。

<任意のコマンド> | awk '{print strftime("[%Y/%m/%d %I:%M:%S] ") $0}'

strftime() はミリ秒単位の表示ができないっぽい。date で代替もできなそう[1]だし、しかたない。

結果、こうなる。

[kuro@localhost ~]$ vmstat 1 | awk '{print strftime("[%Y/%m/%d %I:%M:%S] ") $0}'
[2015/11/01 05:04:04] procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
[2015/11/01 05:04:04]  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
[2015/11/01 05:04:04]  1  0      0 483204  23324 363936    0    0   145     2   32   44  0  1 99  0  0
[2015/11/01 05:04:05]  0  0      0 483172  23324 363960    0    0     0     0   26   36  0  0 100  0  0
[2015/11/01 05:04:06]  0  0      0 483172  23324 363960    0    0     0     0   26   36  0  0 100  0  0
[2015/11/01 05:04:07]  0  0      0 483172  23324 363960    0    0     0     0   27   42  0  0 100  0  0

関数にする

関数にする場合は、例えばこんな感じ。

#!/bin/bash
function add-timestamp () {
        f="[%Y/%m/%d %I:%M:%S] "
        for opt in "$@"; do
                case "$opt" in
                        '-f' | '-format' )
                                f="$2"
                                ;;
                esac
        done
        cat - | awk "{print strftime(\"$f\") \$0}"
}

-format(-f でもよい)で任意のフォーマットを指定できる。何も指定しなければデフォルト(”[%Y/%m/%d %I:%M:%S] “)。

こうやってつかう。

<任意のコマンド> | add-timestamp
<任意のコマンド> | add-timestamp -f "<%I:%M:%S> "

結果、こうなる。

[kuro@localhost ~]$ vmstat 1 | add-timestamp
[2015/11/01 05:18:48] procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
[2015/11/01 05:18:48]  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
[2015/11/01 05:18:48]  2  0      0 482800  23648 364060    0    0   110     2   30   42  0  0 99  0  0
[2015/11/01 05:18:49]  0  0      0 482768  23648 364060    0    0     0     0   33   46  0  1 99  0  0
[2015/11/01 05:18:50]  0  0      0 482768  23648 364060    0    0     0     0   27   38  0  0 100  0  0
[2015/11/01 05:18:51]  0  0      0 482768  23648 364060    0    0     0     0   23   37  0  0 100  0  0

どうにかしてミリ秒出せないかな、これ。


  1. やってみたら全行のタイムスタンプが同じ時刻になってダメだった []

自分が他校の何期生相当かすぐわかる、ギター合奏クラスタ用 Web サービス『多摩高期数変換機』をつくった

背景

ギター合奏界隈で集まってお互いに自己紹介するときに、『○○高校の△期の□□です』という言い方をよくします。ぼくでいえば、『多摩高校の 48 期の黒井です』といった具合ですね。

これ、同じ学校であればすぐにどの世代か理解できて自分との関係性も導き出せるのですが、当然ながら他校の数字で言われてもよくわかりません。それどころか、学校によっては、”期” ではなく定期演奏会の “回” で数えているところもあります。

もちろん、他校出身の友人がいるのであれば、そのひとを基準に計算することは容易いし、慣れてくれば自分の頭の中に対応表が出来上がってくるものです。最近では『多摩高校換算で××期相当』と自己紹介に最初から含めてくる強者もよく目にするようになりました。

とはいえ、そういうコミュニティの空気に慣れるまでは、それはなかなかできるものではありません。

相手の世代がわかることで、初対面でも、コンクールで弾いていた曲、交流会であったできごと、共通の先輩や後輩など、話題の幅がかんたんに広がります。とくに相手が自分に近い代である場合はなおさらで、思い出話に花を咲かせやすくなるというものです。

そんなわけで、初対面でも話のきっかけを増やせるかもしれない仕組みのひとつとして、これを作りました。

……もともとこういう変換機構は欲しいなあとは思ってはいたのですが、実装に着手したいちばん直接的な理由は、最近老害おじさん友人がこんなことをやっていたからです。

作ったもの

これです。

多摩高期数変換機

これは、中学や高校でギター合奏を行う部活動や同好会に所属している、または所属していた方々を対象にした、

  • 自分の学校名と期数』か『自分の学校名と引退時の定期演奏会の回数』か『自分の誕生年度』を入力すると
  • 自分がほかの学校では何期生に相当するのか、第何回の定期演奏会の代かがわかる

という機能をもつ Web サービスです。

つかいかた

スマートフォン世代の方々にはすぐ馴染めるようなインタフェイスにしたつもりです。

  1. 最上段のタブで変換方法を選びます
    • [期から] は、[学校] と [] を元に計算します
    • [定演から] は、[学校] と [引退時の定演] を元に計算します
    • [誕生年度から] は、[誕生年度] を元に計算に変換します
  2. 変換方法に応じた入力欄が表示されるので、すべての欄で適切な値を選択します
  3. 入力が完了すると、画面下部に結果が表示されます
  4. お好みで [結果をツイートする] ボタンでツイートします
使い方

使い方

また、右上の [設定] ボタンからは、いくつか挙動を任意で変更できます。設定は任意のタイミングで変更可能で、変更は即座に結果に反映されます。

設定

設定

[定演の回を表示する] のチェックを入れると、計算結果に期数だけでなく、その期の代が引退したときの定期演奏会の回数も併せて表示されます。デフォルトは無効です。なお、定期演奏会の回数はツイートには含まれません。

[マイナス表示を許可する] のチェックを入れると、”1 期” のひとつ上を “0 期”、もうひとつ上を “-1 期”…… とさかのぼって表示するようになります。デフォルトは無効で、”1 期” より上の代はすべて “-” と表示します。”1 期” のひとつ上を “0 期” にするべきか “-1 期” にするべきかは議論の余地がありますが、実装がラクなのでひとまず “0 期” にしています。

考えたことというか工夫というか

世代の区別の根拠は学校によって “期” だったり “回” だったりといろいろなので、そういった差を吸収するため、複数の変換方法を用意しました。

また、処理を JavaScript で完結させているので、サーバとの余計な通信は発生しません。

拡張しやすくするため、学校の情報はすべてひとつの連想配列にまとめました。結果の表示枠もすべてその配列から動的に生成させているので、配列に一行足すだけで学校が追加できます。

あとは結果が “-” になる学校の分はツイートに含めないとか、入力時に学校に応じて期の選択肢が変わるとか、細かなところは手を入れています。

未実装、あるいは検討の余地

あくまで機械的に算出しているため、『定期演奏会が必ず一年に一度だけ開催される』という暗黙の前提を置いています。この前提に従っていない歴史がある場合は、計算結果が狂います。

おくさまに見せたら、『Facebook か Twitter と紐付けて結果をデータベースに貯めて、誰と同期だとか誰が後輩で先輩だとかわかるようにしたら?』と言われました。さすが IT やさんです。

まとめ

本業のおしごとでは IT 系と言いつつ Web アプリケーション系のコードを書く機会がまるでないので、久々に趣味のプログラミングって感じでおもしろかったです。

jQuery Mobile、便利ですね。まともに使ったのは恥ずかしながら初めてだったんですが、好きになりました。

こういうのって、コードを GitHub に載せるとイイんでしょうか。最近のお作法ってどうなんだろう。

ちなみにこの勢いに乗って、実は Python + jQuery でそれなりに機能する CGI を作ったんですが、それはまた別のお話。一般公開はしていないです。


卒業論文のLaTeXテンプレート

そつろんをLaTeXで書くことになったんだけど、研究室にテンプレートが無かったのでせんぱいのを改造したりインターネットで調べたりしつつ作った。細かいところはいろいろセオリィに反しているのかもしれない(よくしらない)けど、簡単につかえるようにはしたつもり。

うちの研究室用なので他の団体様で使えるかはわかりませんが、使えそうならどうぞ。

卒業論文用に作ったけど、ちょろっと書き換えれば修士論文にもたぶん使えると思う。文字コードは研究室で使う関係でEUC-JPです。

中の[main.tex]をいじくり回せばどうにかなる。そのままコンパイルすると説明書みたいなのが出力される(同梱の[main.pdf]がそれ)。簡単なLaTeXコマンドの解説も書いたので、たぶんだいたいどうにかなる。わからないところはぐぐればどうにかなる。

@ymrl も卒業論文をLaTeXで書く解説してくれていますし、今のわいらぼ三年生、来年がんばってくださいヽ( ・∀・)ノ


GCLとSBCLのインストール周りとSBCLのバグっぽいのの対処

いろいろ方法まとめ。

まずはインストール方法。Mac OS XとWindowsでGCLとSBCLをいんすこする。MacにGCL入れるのが一番面倒なんだけど、そのかわり個人的に一番使いやすいのもMac上でのGCL……。

次がバグなんだか仕様なんだかわからないけど、SBCLでprintとreadを続けて書いたときに、なぜかprintより先にreadが呼ばれてしまうというよくわからない挙動に対応するための方法。print -> readの流れをprin1 -> terpri -> readにするだけ。