トップ 最新 追記

Days of Speed

過ぎゆく日々を書こう。忘れっぽい未来の自分のために


2013-03-04

_ 宛名の敬称が「先生」

野方純先生

4月から月曜と金曜、とあるトコロでちょっと教えることになりそうなのですが、そのとあるトコロから送られてきた郵便物の宛名の敬称が「先生」ってなってた。

あー…。

Tags: life
本日のツッコミ(全1件) [ツッコミを入れる]

_ 田吾作 [じゃあ純ちゃん先生ってタイトルで呼ぶわ]


2013-03-05

_ IKEAで机を買ってきてスタンディングデスクにした

模様替えの様子ノートが置けるのは嬉しい

何年か前から自宅の環境を座卓にしてたのだけど、座卓は「リラックスしすぎる」、「あぐらをかいた状態で背中を丸めてしまう」という欠点があって、前者は「ダラダラ作業をしてしまう」、「疲れてそのまま畳に寝てしまう」、後者は「腹筋、背筋が弱まって足腰を悪くする」という事を引き起こしてました。

ということでIKEAでテーブルの天板と脚を買ってきて、スタンディングデスクを作りました。

天板は150cmと広いのでノートPCを置いて作業ができるし、脚は伸縮式なので今はスタンディング用に90cmいっぱいまで伸ばして使って、スタンディングを辞めたい時は70cmに縮めれば、普通の机として使えるから、7000円でこれはお買い得だったかも。

Tags: life lifehack

2013-03-09

_ オープンソースカンファレンス2013@Tokushumaに関西Debian勉強会と姫路IT系勉強会で出たよ

ブースの様子

当日の写真はこのへんとか。 https://plus.google.com/photos/110468748131645597665/albums/5853606179156699457

OSC徳島に行ってきました。 最初は一人で行くつもりだったのが、いつの間にか関西Debian勢が車で行く事になり、かなり楽ちんな旅でございました。 (1名某みずのさんが花粉症でぐしゅぐしゅだったのを除く(笑))

えーっと。イベントとしてどうだったのかというと、あまり覚えてません。 というのも、渋滞に巻き込まれて遅れて着いたこともありますが、着いてからJAWS三都物語とのGoogleハングアウトを使った中継のお手伝いをしたり、なんだかんだであっという間に終わってしまった印象があったからでございます。

姫路IT系勉強会で言うと、最近、awkで活躍している、たくぼさんのawk GLデモや松岡夫妻がいたので、まあなんとかなりましたが、地域コミュニティが他県に関西圏外でPRはちょっと厳しかったかなぁ。

そんなわけで楽しいイベントでした。


2013-03-28

_ Express5800/S70 タイプhfがきた

うちのサーバーもそろそろ入れ替え時かなと思って、NTT-X Storeで10980円で売ってたExpress5800/S70 タイプhfを注文したら1日で届いた。はっやー。

_ Software Design 総集編 【2001~2012】の献本が届いた

Software Design 総集編 【2001~2012】
SoftwareDesign 編集部
技術評論社
¥ 2,138

Software Designにいくつか記事を書かせてもらった、ということで技評さんから、Software Design 総集編 【2001~2012】をいただきました。 2012年までといえば、ほんのちょっと前まで入ってるし、買い逃した号も入ってるので、これはうれしいなぁ。ありがとうございました。

みんな、買ってね。


2013-03-29

_ シェルスクリプト(bash)のメッセージを国際化する 2013年版

シェルスクリプトのメッセージを国際化するといえば「bash スクリプト内メッセージの国際(カタログ)化」に書かれている方法が有名ですが、この方法はセキュリティ上の問題(シフトJISや中国語のエンコーディングではダブルクォーテーションを無効にできてしまうなど。くわしくは「bash - GNU `gettext' utilities」を参照)から現在、非推奨になっています。

現在推奨されているメッセージの国際化は、手順自体が大幅に変わったワケではありませんが、全体を通してまとまった文書は日本語ではないようなので、まとめておきます。

参考

以前との違い

大きな違いとしては、国際化したいメッセージの部分を「$"Msgid"」と書いていたものが、「"$(eval_gettext "Msgid")"」という書き方になりました。それにともない、事前にラッパーのgettext.shを読み込ませる必要があります。

シェルスクリプトのメッセージを国際化する

ここからは、シェルスクリプトのメッセージを実際に国際化対応していきます。

サンプルと実行例

サンプルとしてHello Worldと表示するシェルスクリプトを使いました。

#!/usr/bin/env bash
# hello.sh -- say hello script
echo hello world

実行例

$ ./hello.sh
hello world

メッセージのカタログ化事前準備

メッセージをカタログ化を準備するため、ラッパーのgettext.shを読み込ませます。 読み込ませる方法は「. gettext.sh」(一番前にドットがあります。)という行を追加します。 追加する行は、先頭の部分、シェバンの下あたりに書くとよいでしょう。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo hello world

メッセージをカタログ化

国際化したいメッセージをカタログ化します。 まず、メッセージの部分をダブルクォーテーションで囲み、その前に「eval_gettext」と書きます。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo eval_gettext "hello world"

eval_gettextはgettext.shに含まれる関数ですが、このままでは文字列としか扱われてないので、バッククォート「`」もしくは「$(」と「)」でeval_gettextと文字列をくくり、関数として実行されるようにします。そして「$(」と「)」の外をダブルクォーテーションでくくります。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh
echo "$(eval_gettext "hello world")"

potファイルの生成

xgettextを使って(bash --dump-po-stringsは使わない)メッセージカタログの元になる、potファイルを生成します。「-o」オプションで出力ファイル名をつけて、xgettextを実行します。

$ xgettext -o hello.pot hello.sh
$ cat hello.pot

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 22:25+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: hello.sh:4
#, sh-format
msgid "hello world"
msgstr ""

メッセージカタログを作成

potファイルをコピーし、言語のpoファイル(メッセージカタログ)を作成します。

$ cp hello.pot ja.po

適当なエディタを使い、ja.poをそれぞれの言語に翻訳します。 poeditなどの専用エディタならpoファイルの情報はそれぞれ適切に設定されますが、テキストエディタのみで作業する場合は、最低「Content-Type:」のCHARSETはUTF-8に設定してください。

$ cat ja.po

# hello ja.po
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-28 22:26+0900\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: Japanese\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" ← CHARSETをUTF-8にしておく
"Content-Transfer-Encoding: 8bit\n"

#: hello.sh:4
#, sh-format
msgid "hello world"
msgstr "こんにちは 世界" ←msgidに対応した文を翻訳する

poファイル(メッセージカタログ)のコンパイルと配置

poファイルをコンパイルしmoファイルを生成。メッセージカタログのディレクトリに配置します。

まずカレントディレクトリにmoファイルを置くディレクトリを作成します。

$ mkdir -p ja/LC_MESSAGES

poファイルをコンパイルします。moファイルの出力先は「-o」オプションで変更できるので、ja/LC_MESSAGES/(アプリケーション名).mo とします。

$ msgfmt -o ja/LC_MESSAGES/hello.mo ja.po

メッセージカタログの適用テスト

メッセージカタログが生成できたので、スクリプトにそれぞれの言語でメッセージカタログが適用されるかテストします。

通常、メッセージカタログは /usr/share/locale/ja/LC_MESSAGES (日本語の場合)以下に置かれますが、メッセージディレクトリを指す環境変数 TEXTDOMAINDIR と、アプリケーション名を指す環境変数 TEXTDOMAIN を変更するとカレントディレクトリを指定できるので、それぞれを変更してテストをおこないます。

LANGにCを設定した場合
$ LANG=C TEXTDOMAIN=hello TEXTDOMAINDIR=. ./hello.sh
hello world

LANGにja_JP.UTF-8(日本語)を指定した場合
$ LANG=ja_JP.UTF-8 TEXTDOMAIN=hello TEXTDOMAINDIR=. ./hello.sh
こんにちは 世界

それぞれ適用できました。

TEXTDOMAINDIRの設定とメッセージカタログのアップデート

スクリプトを実行する際、いちいち「TEXTDOMAIN=hello TEXTDOMAINDIR=.」をつけての実行は面倒なので、スクリプトの中に書いてしまいます。

#!/usr/bin/env bash
# hello.sh -- say hello script
. gettext.sh

TEXTDOMAIN=hello
export TEXTDOMAIN
TEXTDOMAINDIR=/home/hoge/src/hello/
export TEXTDOMAINDIR

echo "$(eval_gettext "hello world")"

TEXTDOMAINは変わりませんが、TEXTDOMAINDIRは、「.」のままではカレントディレクトリを示して、別のディレクトリからスクリプトを実行するとメッセージカタログが適用されないので、フルパスでスクリプトのディレクトリを指定します。

スクリプトが変更されたので、メッセージの位置が変わります。ですのでメッセージカタログもアップデートします。

xgettextでpotファイルの生成は同じですが、msgmergeを使ってja.poをアップデートします。

$ xgettext -o hello.pot hello.sh
$ msgmerge -U ja.po hello.pot

上のような些細な変更ではなくメッセージの追加などあれば、未翻訳の部分もあるのでpoファイルに未翻訳部分の翻訳も追加します。 追加が終わればpoをコンパイルします。

$ msgfmt -o ja/LC_MESSAGES/hello.mo ja.po

正しくメッセージカタログが適用されるかテストします。

英語
$ LANG=C ./hello.sh
hello world

日本語
$ LANG=ja_JP.UTF-8 ./hello.sh
こんにちは 世界

ディレクトリを変更してもメッセージカタログが適用されるかテストします。

$ cd ~/
$ LANG=C src/hello/hello.sh
hello world
$ LANG=ja_JP.UTF-8 src/hello/hello.sh
こんにちは 世界

これで問題なくメッセージカタログが適用されるようになりました。

文字列を非推奨の「$"..."」で囲んでいるスクリプトにxgettextを使うと

文字列をこれまで解説をした「"$(eval_gettext "...")"」ではなく、非推奨の「$"..."」で囲んでいるスクリプトに、xgettextでメッセージカタログを生成しようとすると警告されます。

$ cat hello-old.sh
#!/usr/bin/env bash
# hello.sh -- say hello script
echo $"hello world"
$ xgettext -o hello-old.pot hello-old.sh
hello-old.sh:3: 警告: 文法 $"..." はセキュリティ上の理由で推奨されません. 代わりに eval_gettext を使ってください

bash --dump-po-stringsでは何も出ません。

$ bash --dump-po-strings hello-old.sh > hello-old.pot

ということで、メッセージカタログの作成にはxgettextを使いましょう。

_ シェルスクリプトだけで空白で区切られた文字列から特定部分だけ抜き出し、入れ替えて表示

シェルスクリプトを使っていて空白で区切られた文字列「"AAA BBB CCC DDD EEE"」から2番目のBBBと5番目のEEEを取り出し、入れ替えて「EEE BBB」と表示したい場合、cutやawkを使うのもよいですが、いったん配列に入れると位置を指定して取り出すことができます。

1: T="AAA BBB CCC DDD EEE"
2: F=(${T})
3: echo "${F[4]} ${F[1]}"

EEE BBB

1行目: 空白で区切られた文字列「"AAA BBB CCC DDD EEE"」が変数Tに入ってます。

2行目: 配列に代入するとき、F=(A B C D E)のようにするとF[0]=A, F[1]=Bのように配列Fにそれぞれ分割されて代入されます。ここに空白で区切られた文字列$Tを指定すると、F[0]=AAA, F[1]=BBBのように分割されて配列Fに代入されます。

3行目: ということで、F[4]に文字列「EEE」、F[1]に文字列「BBB」が入っているので、それぞれ指定してechoで表示しています。


2013-03-31

_ 花見と散歩

彼女の人と花見がてらの散歩。

そして、散歩先であった謎のモニュメント。あれはなんだ?

Tags: life

2001|12|
2002|01|02|03|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|06|08|12|
2011|01|02|03|06|07|08|09|10|11|12|
2012|01|02|03|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|12|
2014|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|10|11|12|
2017|01|02|

クリエイティブ・コモンズ・ライセンス Jun NOGATA を著作者とするこの 作品クリエイティブ・コモンズの 表示 - 継承 4.0 国際 ライセンスで提供されています。