2015年4月28日火曜日

mgとgreple

メール本文などのJISコードで保存されている日本語ファイルから文字列を検索するためにmgというプログラムを使っていました。
mg-5.0.1.3
http://utashiro.hatenablog.com/entry/20050110/1105360517
会社のファイルサーバーのデフォルトの文字コードをUTF8に変更した後、mgコマンドを使おうとすると、うまく動かないことに気が付きました。LANG=ja_JP.UTF-8
の環境でコマンド行で
$ mg -j jis "日本語" ファイル名
とすると、”日本語"の部分はUTF8になり、mgコマンドにもUTF8で渡されます。UTF8はどうなっているのかと思い、上記のblogを見てみると、対応していないようです。
mg の Unicode 対応
http://utashiro.hatenablog.com/entry/20060927/1159335703
だめもとで、リポジトリを見てみると
mg is obsolete now. use https://github.com/kaz-utashiro/greple instead.
https://github.com/kaz-utashiro/mg
とあり、これからはgrepleを使ったほうがよいようです。
grepleの様子を上記のblogで探してみると…、
greple のリファクタリングと Getopt::EX
http://utashiro.hatenablog.com/entry/2015/02/02/180448
で、2015年2月2日にgreple改修中とあります。となるとリポジトリにある開発版を使ったほうがよいかもしれません。そこで、
https://github.com/kaz-utashiro/greple/tree/develop
から開発版をもってきて動かしてみるとにしました。 手元のFreeBSD 9.1で展開し、
greple-develop/bin/greple 
を動かしてみると…
App::Greple::default: Can't locate App/Greple/default.pm in @INC (@INC contains: /usr/local/lib/perl5/site_perl/mach/5.16 /usr/local/lib/perl5/site_perl /usr/local/lib/perl5/5.16/mach /usr/local/lib/perl5/5.16 /usr/local/lib/perl5/site_perl/5.16 /usr/local/lib/perl5/site_perl/5.16/mach . /home/ss/greple-develop/lib) at (eval 12) line 2.
BEGIN failed--compilation aborted at (eval 12) line 2.
 at /ss/greple-develop/lib/Getopt/EX/Loader.pm line 71.
となり、App/Greple/default.pmというモジュールが必要なようです。
ヤマカンで
greple-develop/lib/App/Greple/default.pm
というファイルを作ってみましたが、同じエラーになります(私はPerlのプログラム作成はできないのです)。そこで、同じディレクトリにあるCommon.pmというファイルを眺めてみました。
package App::Greple::Common;

use strict;
use warnings;

use Exporter 'import';
our @EXPORT      = ();
our %EXPORT_TAGS = ();
our @EXPORT_OK   = qw();

use constant FILELABEL => '__file__';
push @EXPORT, qw(FILELABEL);

*opt_d  = \%main::opt_d;      push @EXPORT, qw(%opt_d);

*setopt = \&main::setopt;     push @EXPORT_OK, qw(setopt);
*newopt = \&main::newopt;     push @EXPORT_OK, qw(newopt);

1;
default.pmというモジュール名からして、形だけあれば動くかもしれないと思い、以下のような先頭の宣言部分と、返り値の部分だけをdefault.pmに書き込んでみました
package App::Greple::default;

1;
そして実行してみると…、今度は動きます。実際に文字列検索をしてみましょう。
$ ./greple-develop/bin/greple "委員会" Mail/*
10:>>(3)運営委員会を、1日目…
15:>> ※運営委員会でも…
となってなんとなく動きます。ただ、いろいろなファイルに試してみると、
utf8 "\x81" does not map to Unicode at ./greple-develop/bin/greple line 753.
という警告が出たり、perlプロセスが長時間動いたたままになったりすることがありました。
オプションを変えて試してみると
$ ./greple-develop/bin/greple --icode=guess "委員会" Mail/*
のように--icode=guessというオプションを付けるとうまくいきそうです。
ということで、システムに入れてみることにしました。ただ、インストーラーがなくこれらのファイルをどのように配置すればよいかよくわかりません。もう少しブログを読んでみると、どうもこのディレクトリ構造のままで置いておくとうまく動きそうなことが書いてあります。
現在の greple はモジュールに分割されてはいるが、clone するなり tz を展開するなりして、実行形式を直接指定するかシンボリックリンクを張れば実行できるようになっている。
そこで greple-developを/usr/local/etcに置き、/usr/local/binからgreple-develop/bin/grepleにシンボリックリンクを張ることにしました。
$ sudo mv -i greple-develop /usr/local/etc
$ cd /usr/local/bin
$ sudo ln -s /usr/local/etc/greple-develop/bin/greple
$ ls -l ./greple
lrwxr-xr-x  1 root  wheel  40  4月 28 16:29 ./greple -> /usr/local/etc/greple-develop/bin/greple
$
実行してみます。
$ greple --icode=guess ありがとう Mail/*
Mail/119:ありがとうございます。
動くようです。
もう少しブログを見てみると
実は greple で PDF ファイルを検索できる
http://utashiro.hatenablog.com/entry/2014/01/10/132004
とか書いてあります。試してみましょう。
$ greple -p "分散" doc/release.pdf
分散電源
… 

$
動きますね。便利かもしれません。

FreeBSDでconvmvを使ってファイルシステムのファイル名をEUCからUTF-8へ変換する

会社ではFreeBSD 9.1を利用したファイルサーバーで利用しています。
長年の経緯からファイルシステム上のファイル名はEUCを使っていました。
そのため、デフォルトのLANG環境変数もja_JP.eucJPとしてきましたが、
2013年ぐらいから
  • 漢字コードとしてEUCは使えずUTF-8だけというアプリケーションが増えてきた
  • UTF-8な文字列をEUCなファイルにコピーペーストできない(EUCで表現できない文字が使われているためのようです)
といった問題がでるようになり、不便を感じていました。
そこで、今年(2015年)になり、
ファイルシステムの名前とLANG環境変数をUTF-8に変更することを決断しました。
決断が遅れたのは
ファイルシステム全体の変更になりそれなりの危険性があると考えたためです。
そこで、まず自宅で同様な構成を取っていてるファイルサーバーで変更し、
2ヶ月程度使用して問題ないことを確認し、やっと実行に移すことにしました。

手順は簡単です。
  1. ファイルシステムとしてZFSを利用していたので、実行前にスナップショットを取得
  2. zfs snapshot zfsファイルシステム@タグ(私は日時にしています)。
  3. ファイル名が変更されるものの一覧を確認する
  4. convmv -r --nfc -f euc-jp -t utf8 /ディレクトリ
    ファイル名一覧…
  5. 255文字以上のファイル名については警告が表示されるので、 これらは事前に255文字以内になるようにファイル名を変更する
  6. 変更
  7. convmv --notest -r nfc -f euc-jp -t utf8 /ディレクトリ
約2TBのファイルシステムで、一度に変換せず、主要ディレクトリごとに2.と3.を繰り返えしたため、全体で6時間ほどかかりました。

--nfcオプションと255文字問題については、以下のblogで解説があります。
ドラえもん問題
http://key2.jp/~yskhashi/wordpress/?p=427
主要部分を引用します。
  • 古いファイルシステムの制約に合わせているのか、ファイル名の長さが255byteに制限されていた。convmv の中の $maxfilenamelength1024にしとけばいいだろう。
  • でも、たまにファイルが開けなくなって、規則性を見ようとしたら、あんがい簡単に判明した。ファイル名に濁点、半濁点がある時で、これが原因となるNo.1といえば、そう、Unicode Normalization!(シラネーよ)
    • 正規化形式 D (Normalization Form D, NFD)
    • 正規化形式 C (Normalization Form C, NFC)
    OS XはNFDを使う。Windowsやその他はNFCを使う。

2015年4月23日木曜日

MacBook Pro(Retina, 13-inch, Late 2012)/MacOS X 10.9.5でAppStore.appにアクセスすると接続できません/Connection failedになる

今日(2015/04/23)、Macのソフトウェアアップデートを確認するために、
App Storeを起動、Apple IDとパスワードを入力すると「Connection Failed」となりました。
回復させようと以下の手順を試しましたが、改善されません。
OS X:「接続できません」または「Mac App Store に接続できません。インターネットへの接続が必要です」というメッセージhttps://support.apple.com/ja-jp/HT203811
いろいろと試してみると、OSの再インストール(起動時にCommand-Rを押し、表示された画面から実行できます)をすると、App Storeにアクセスすることができるよういなります。しかし、その後、App StoreからSecurity Update 2015-004を適用とすると、同じ現状になるようです。
もう少し、検索エンジンで探してみると、
【回避策あり】OS Xのセキュリティアップデートに不具合 一部のMacでhttpsでのアクセスに影響
http://reynotch.blog.fc2.com/blog-entry-1109.html
で証明書がおかしいのではないかという推測がされています。
OSの再インストールは時間がかかるので、上記のアップデートを適用せずに様子を見ることにします。
10.9.5がインストールされた別の3台のMac Miniでは発生していないので、特定の機種で発生するのかもしれません。

2015年4月16日木曜日

Teratermでscreenコマンドを使うと画面が80桁になってしまう

TeratermでFreeBSD 9.1/9.2のscreenコマンドを使うと画面が80桁になってしまいました。調べると以下のサイト
screenで画面サイズが勝手に変わってしまう事象の対策(メモ)
http://blog.goo.ne.jp/sohgoh/e/362865b122f5151f78ea7c7f16267659
で回避方法が書かれており、そのように設定をすると現象は出なくなりました。

設定は、.screenrcに以下を追加するというものです。
termcapinfo xterm 'is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l'
これは端末起動時の初期化エスケープシーケンスを設定するものです。
意味を以下を参考に調べてみました。
対応制御シーケンス
http://ttssh2.sourceforge.jp/manual/ja/about/ctrlseq.html
\E[ :
ESC [ CSI CSIシーケンスを開始 (CSIシーケンスを参照)
CSI r:
CSI Ps1 ; Ps2 r DECSTBM 上下マージン(スクロールリージョン)を設定する。
Ps1    上マージンの行位置。省略時は 1。
Ps2    下マージンの行位置。省略時は画面下端。
CSI m:
CSI Pm m SGR 文字属性を設定する。省略時の Pm の値は 0。(文字属性を参照)
CSI 2J:
CSI Ps J ED 画面消去。Ps の省略時の値は 0。
Ps = 0      カーソル位置から画面末尾までを消去する。
   = 1      画面先頭からカーソル位置までを消去する。
   = 2      画面全体を消去する。
CSI H:
CSI Ps1 ; Ps2 H CUP カーソルを Ps1 行目の Ps2 桁目に移動する。Ps1, Ps2 の省略時の値は 1。
CSI ?7h
CSI ? Pm h DECSET DEC/xterm 拡張のモードを設定する。(モード (DEC/xterm拡張)を参照)
CSI ?1;4;6l
CSI ? Pm l DECRST DEC/xterm 拡張のモードを解除する。(モード (DEC/xterm拡張)を参照)
これで画面サイズが変更されないのは謎ですが、もともとのxtermの初期化制御シーケンス「is=\E[!p\E[?3;4l\E[4l\E> 」を入れ替えているようです。