ホーム ダウンロード 使用法 内部実装

UTF-8 Cygwin - 使用法

2006/4/10 - 2007/1/29 (鈴)

概要

現在のところ, ファイル名とフォルダ名,コンソール (いわゆるコマンド・プロンプト) 入出力を UTF-8 化しています。

01:~$ echo ㎥
㎥
01:~$ echo ㎥ | od -t x1
0000000 e3 8e a5 0a
0000004 
01:~$ echo CDE | od -t x1
0000000 43 44 45 0a
0000004 
01:~$ echo ハニホ | od -t x1
0000000 e3 83 8f e3 83 8b e3 83 9b 0a
0000012 
01:~$ 

Life with Cygwin 9. X11 のように xterm だけ UTF-8 化した場合と異なり, ファイル名やフォルダ名も UTF-8 化していますから, それらを見るために nkf は必要ありません。 今までどおりそのまま見れます。

01:~$ ls -l Desktop
lrwxrwxrwx 1 suzuki None 20 May  7 17:55 Desktop -> profile/デスクトップ/

さらに,次の2点でデフォルトコードページ (日本語環境では Shift JIS の変種である CP932) を利用できます。

基本的に,今までと操作方法,操作感に大きな違いはありません。
一見すると不思議に思えますが, ここで UTF-8 でファイルやフォルダを命名しても, 従来の Shift JIS 環境から見れば,きちんと Shift JIS になっています。 逆も成り立ちます。 ファイルシステムに格納される名前は, いずれの場合も Unicode であることに注意してください。

環境変数とファイルの内容についてはノータッチです。 環境変数の取り扱いについては議論の余地がありますが, ファイルの内容については,Unix としての基本にかかわることですから, 取り扱い方法に変更予定はありません。 ファイルを保存するとき, ファイルの名前は Unicode に変換されて Windows API に渡されますが, ファイルの内容は従来どおりバイト列として記録されます (ですから,たとえば, text モードでマウントしているフォルダ上にコマンド出力をリダイレクトすると Unicode と復帰改行のバイト列が混在して内容が壊れる, といったような不具合は,従来と同じく,ここでも発生しません)。

日本語環境での従来との主な操作上の違いは次のとおりです。

設定ファイル

UTF-8 Cygwin のための設定を,ダウンロードページに用意した設定ファイルからの抜き書きで説明します。

~/.bashrc

従来の Shift JIS 用の設定と変わりません。 stty kill undef は ~/.inputrc で C-u を再定義するために必要です (再定義しなければ不要です)。 bash 3.0 のプロンプト表示にはバグがあるので回避します (Cygwin の小 bug 参照。 2006/11/11 配布の bash ではバグは直っています)。

# hack against bash-3.*
stty kill undef
[ $TERM = cygwin ] && TERM=cygwinB19
[ $TERM = cygwinB19 ] && alias man='TERM=cygwin man'

プロンプトの設定です。

if [ $TERM = dumb ]
then PS1='$?$SHLVL:\w\$ '
else PS1='\[\e]0;\w\a\e[36m\]$?$SHLVL:\w\[\e[32m\]\$\[\e[0m\] '
fi

重要なのは ls での --show-control-chars と, 環境変数 LESS での "r" です。 lsless をバイト透過にします。

alias ls='ls -F --show-control-chars'  la='ls -a'  v='ls -l'
export LESS=MrXEd

~/.inputrc

従来の Shift JIS 用の設定と変わりません。 1 行目では C-u (Control を押しながら u) を補完候補一覧専用に再定義しています (これは必須ではありません)。 2 行目と 3 行目では UTF-8 入出力のためにバイト透過にします (これは必須です)。

C-u: possible-completions
set convert-meta off
set output-meta on

~/.vimrc

従来の Shift JIS 用の設定は使えません。 encoding=utf-8 にする必要があります。 ちなみに fileencodings を設定すれば各種のコード系を自動判別してくれますが, 指定順序に気を付ける必要があります。

set encoding=utf-8
set fileencodings=iso-2022-jp,utf-8,euc-jp,cp932
let $LANG='ja'

/usr/lib/python2.4/site-packages/sitecustomize.py

従来の Shift JIS 用の設定は使えません。検索用に正規化した名前として 'UTF-8' でも 'utf-8' でもなく 'utf_8' を与えます。

from encodings import aliases
aliases.aliases['us_ascii'] = 'utf_8'

混乱を避けるために,下記の設定もしておくのが無難でしょう (ただし,これは必須ではありません。 'shift_jis' のままにすることも合理的です)。

import sys
sys.setdefaultencoding('utf-8')

Shift JIS 互換変換の制限事項

前述のように, UTF-8 バイト文字列から Unicode 文字列への変換時に UTF-8 で解釈できないバイト文字列が与えられたとき, 従来どおりのコードページ (日本語環境ならば Shift JIS の一変種) で解釈を試みます。 この単純な仕組みでも Shift JIS 漢字文字列のほとんどは正しく変換できます。 とりわけ,ASCII と第1水準漢字だけの場合, 原理的に誤変換は皆無です。

2バイト長の UTF-8 マルチバイト文字列は, 最初が 0xC0 〜 0xDF, 次の1バイトが 0x80 〜 0xBF です。 3バイト長の UTF-8 マルチバイト文字列は, 最初が 0xE0 〜 0xEF,次の2バイトが 0x80 〜 0xBF です。 4バイト長の UTF-8 マルチバイト文字列は, 最初が 0xF0 〜 0xF7,次の3バイトが 0x80 〜 0xBF です。 ASCII と第1水準の Shift JIS 漢字だけでは, このパターンに適合するバイト列を構成できません。

ただし,逆にいえば, 半角カナや第2水準漢字を含む Shift JIS 文字列のなかには, UTF-8 と誤認され,誤った Unicode に変換されるものがある, ということです。 もっとも,普通は UTF-8 と解釈できない他の文字並びと抱き合わせになるため, 誤認は起こりません。 ですから,この Shift JIS 自動再解釈機能は実用上は便利に使えます。 それでも他の自動コード判定プログラムと同じく,100% あてにすることはできません。 確実なのは UTF-8 ⇒ Unicode 変換です。

現行 3 月 31 日版の実装では, 誤認の起こりやすさがファイル名解釈とコンソール出力で異なっています。 Shift JIS 文字列「ファイル」のように, 誤認される半角カナ文字列 ファに そうでない文字列 イル が置かれているとき,前者は誤認を起こしませんが, 後者は ファ を誤認します 次の段落で述べる問題とあわせ,コンソール出力の実装の要改良点です。 なお,「重要ファイル」 のように, UTF-8 と解釈できない文字列がに置かれているときは, どちらも誤認しません。

さらにまた, コンソールに一度に出力される Shift JIS 文字列の末尾が, マルチバイト文字の第1バイトであって, 次の出力の第2バイト以降がたまたま UTF-8 として妥当な構成だった場合, 第2バイト以降が UTF-8 と誤認され,文字化けが起こります。

ただし, この現象はテキストファイルを cat で流し読みしたときに発現することがありますが, 普通そうするように more や less で出力を区切った場合はまず発生しません (機構上,行単位のバッファ掃き出しをしている場合は発生しません)。 出力をリダイレクトしてファイルに保存する場合や, もともと UTF-8 文字列の場合は,発生することは原理的にありません。

追記: グループ名「なし」問題についても参照してください。

シンボリック・リンク

シンボリック・リンクを実装するショートカットファイルの形式は従来どおりです。 双方向に互換性があります。 つまり,今まで作ったシンボリック・リンクはそのまま使えますし, ここで作ったシンボリック・リンクは,Cygwin を昔に戻しても, やはりそのまま使えます。

ただし,この互換性維持のため,従来と同じような制限があります。 すなわち,

下記の例で Bartók が シンボリック・リンク BBで Shift JIS 表内の Bartok に近似されていることに注意してください。 ファイルシステムが FAT32 の場合,これでもリンクとして機能するようですが, デフォルトである NTFS の場合,下記のようにエラーになります。

01:~/tmp$ ls -l
total 0
drwxr-xr-x+ 2 suzuki None 0 Apr 10 16:42 Bartók/
01:~/tmp$ cd Bartók
01:~/tmp/Bartók$ cd ..
01:~/tmp$ ln -s Bartók BB
01:~/tmp$ ls -l
total 1
lrwxrwxrwx  1 suzuki None 6 Apr 10 16:44 BB -> Bartok
drwxr-xr-x+ 2 suzuki None 0 Apr 10 16:42 Bartók/
01:~/tmp$ cd BB
bash: cd: BB: No such file or directory
11:~/tmp$ 

mount コマンドと mount テーブル

mount テーブルの情報をレジストリに保存する形式は従来どおりです。 双方向に互換性があります。 つまり,今まで mount コマンドで行った設定はそのまま有効です。 また,ここで mount コマンドを実行したとき, その設定は,Cygwin を昔に戻しても,やはりそのまま有効です。

ただし,実行時に mount テーブルを保持する共有メモリの情報が UTF-8 化されていますから, もしも漢字等を含むパス名をマウントしているときは, cygwin1.dll 変更後にいったんログオフするか, または Windows を再起動する必要があります。
そうしなくても,マウントした漢字フォルダ上の ASCII ファイル名は (UTF-8 でなければデフォルトコードページで解釈するルールが発動して) アクセスできますが, 漢字ファイル名は (旧 mount テーブルの Shift JIS 漢字と,ファイル名の UTF-8 漢字の両方を 同時に満たすことができないため) アクセスできなくなります。

シンボリック・リンクの場合と同じく, 互換性維持のため,従来と同じような制限があります。すなわち,

もしも Shift JIS 表外文字を使った場合でも, 共有メモリは UTF-8 化されていますから,mount を実行した直後は使えます。 しかし,いったんログオフ等して, レジストリから Shift JIS で書かれた mount テーブルを読み直すと使えなくなります。

Mac OS X との相互運用性

ファイル名やフォルダ名を表す UTF-8 文字列を Windows API のために Unicode に変換するとき,全角ひらがな・カタカナと合成用濁点・半濁点 (Unicode の \u3099\u309A ) の組み合わせを, 濁音・半濁音の全角ひらがな・カタカナに置き換えます。

\u304B「か」 + \u3099 (COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK) \u304C 「が」

Unicode において両者は等価であり, Windows では後者が使われるからです。 この処理そのものは (日本人だけのためのダーティ・ハックではなく) Unicode の枠組みに沿ったユニバーサルなものですが, 実用上は Mac OS X との相互運用性を実現するために役立ちます (ちなみに,アルファベットのアクセント記号等についても同様の議論があります。 が, 優先順序として,それらに対する実装はまだです。 この点においてクイック・ハックとそしられる余地があります >_<) 現在のところ,Latin-1, Latin-2, ラテン語 (長音符号付き) およびエスペラントの各アルファベットに対応しています)

Mac OS X は UTF-8 ベースですが, ファイル名の表現方法として前者を採用しています。 そのため, Mac OS X 上で日本語ファイル名を tar 等でアーカイブしたものを UTF-8 Cygwin に持ってきて展開すると, そのままならば濁音・半濁音の箇所で文字化けします。 上記の処理はそれを防ぎます。

下記は実際に Mac OS X でアーカイブした tar ファイルを展開した例です。 tar コマンドが八進表現でエコーバックしているファイル名の 第 4 - 6 バイト \343\202\231 が,\xE3\x82\x99 つまり \u3099 の UTF-8 表現であることに注意してください。

01:~/tmp$ tar xvf ~/beta.tar
\343\203\230\343\202\231\343\203\274\343\202\277.pdf
01:~/tmp$ ls -l
total 124
-rw-r--r-- 1 suzuki None 124265 Apr  7 08:31 ベータ.pdf
01:~/tmp$ 

逆に,UTF-8 Cygwin で作成したアーカイブも Mac OS X で無事に展開できます。 上記と逆の変換が Mac OS X 内部で行われます。


ホーム ダウンロード 使用法 内部実装
Copyright (c) 2006, 2007 OKI Software Co., Ltd.