アカウント名:
パスワード:
ja_JP.SJIS ロケールでは、いわゆる半角カナも含めて、 Shift_JIS を正しく扱います。
ただし、ふつうは ja_JP.SJIS ロケールなんてのが用意されてない だろうから、localedef コマンドを使って作らないといけません。
$ ls /usr/lib/locale/ de_DE en_US.utf8 fr_FR@euro ja_JP.sjis ko_KR.euckr en_US fr_FR ja_JP.eucjp ja_JP.utf8 ru_RU.koi8r $ echo $LANG ja_JP.SJIS $ echo 表表 表表 $ echo 表表 | od -t x1 0000000 95 5c 95 5c 0a 0000005 $
ヒストリとか、カーソル移動とか、編集も問題ありません。
ja_JP.SJIS ロケールは,作成可能でしょうか。
最近流行の,Shift_JIS を厳密に解釈することを求める立場からすると, 0x5C のコードポイントにある文字 (\) は,Shift_JIS ではバックスラッシュ (REVERSE SOLIDUS) ではなくて円記号 (YEN SIGN) です。 そして,ISO C にしろ,POSIX にしろ,バックスラッシュのコードポイントがロケールによって動的に変わってしまう状況は想定していないはずなので, たとえ charmap ファイルは作成可能にしても, それを実際に運用するのは難しいと思います。
たとえば,0x5C の文字は Shift_JIS では円記号だからエスケープ文字ではないはずなのに,プログラムによってエスケープ文字と解釈されたり(しなかったり)するとか。もっとも LANG=ja_JP.SJIS; export LANG とかやったとたんに,既存のシェルスクリプトが軒並み動かなくなったりするのも困りますけどね :)
いや,もちろん,堅いことを言わなければ使えるのはわかりますよ。
CP932 は、日本語版 Windows で使われている文字コードで、(JIS X 02xx の世界から見れば) Shift_JIS にいわゆる「機種依存文字」を追加したものです。が、ミソは、Unicode から見たとき、Shift_JIS と CP932 はそれ以上の差異があるという点です。
それは、CP932 と Shift_JIS とでは、Unicode への変換テーブルに一部相違がある、という点です。そのひとつの例として、CP932 では、0x5c は U+005C に変換されます。ほか、JIS X 0208 に属する文字にも、いくつか相違があります。
問題は、日本語版 Windows では、U+005C は円記号だったりすることなんだけど、いまのところそれは関係ないし。
一方で、伝統的な ja_JP.SJIS では、JIS X 0201 Roman は ISO 646 の思想に従って \ を ISO 646-IRV のそれと同質に 解釈するのが普通だったりしますな。
苦し紛れにそういうことをしていたのは事実ですが, それは「ISO 646 の思想」というほど 確乎としたものなのでしょうか。 ISO 646 は ASCII をもとにした符号化文字集合で, 「各国版 (National version)」として一部の文字を入れ替えた版を作ることを許してはいましたが, そのうちの入れ替えられた文字を別の National version の文字 あるいは「国際参照版 (IRV)」と同等に解釈してよいという規定はなかったと思います。
たとえば,日本版では 0x5C は「円記号」ですが, 韓国版ではこれは「ウォン記号」になります。 これを一緒にされたら困るでしょう。 貨幣価値も一桁くらい違うし :-)
ファイルシステムにファイル名を書き込むなら、そのファイルシステムでサポートするコーディングで格納するべきで、ロケール設定に従うのはちょっと変かなと思う。
これはこれで納得できる考え方ではあります。普通に現実的解法を求めるなら、ほとんど必然的結論とすら言えるかもしれません。
とはいえ、UNIXといえば昔から、カーネル内ではなるべくテキスト表現の方法に依存せず、単なるバイト列として生のまま処理しようとするところに特徴があったという考えもできます。例えばファイルの中身はある長さを持つバイト列というだけあって、カーネルはそれが「80文字レコード」だの「可変長文字レコード」だのといった構造を持っているかどうかは関知しません。UnixやWindowsなどはその点で同じ特徴を持っていますが、そうでないOSもあります。UnixとWindowsでは改行文字が違うと言われることもありますが、それはOSが何か改行文字を特別扱いしているというわけではなくて、それぞれのアプリケーションが特定のバイト列をどう改行と見なすかというだけの違いで、実はアプリケーション毎に異なった扱いでも(OSから見れば)構いません(少なくともUnixでは。Windowsではもしかすると特別扱いがあるのかもしれませんが、寡聞にして知りません)。
ファイル名にしても同様で、伝統的Unixではディレクトリ中のファイル名は(必要ならNULで終端した)14バイト以内(その後もっと長くできるよう拡張された)の列と決まっていただけでした。ファイルシステム自体は、NULだけは特殊な意味を持っていたものの、あとは長さの制限だけしか持っておらず、それを守る限りは、アプリケーションが、ファイル名自身バイナリ列であるようなファイルを使っても、OSは気にしません(ただしカーネル内のnamei()関数が"/"を特別扱いするために、NULに加えて"/"も特別扱いになっています。これは、個人的にはUnixの齟齬の一つと思います)。
しかしファイルシステムにlocaleを持ち込んでしまうと、アプリケーションの指定したファイル名というバイト列が、暗黙の内に別のバイト列に変換されてしまうわけで、これはせっかくの「単なるバイト列」という特徴を崩してしまう気がします。極端な話アプリケーションがファイル名自体がバイナリであるようなファイルを作る場合、あるlocaleの下では同一ではあっても、バイト列としては異なるファイル名に変換されてしまい、アプリケーションが不具合を起こすということもあるでしょう。(まあ、そんな変なファイル名をつける方が悪いというのは常識的には正しい指摘なのですが。)
そういったわけで、私の個人的感情としては、Unixカーネルはあくまですべてを単なるバイト列として扱い、そこにテキスト表現を見いだすのはアプリケーションレベル以上だけにして欲しい、という気持ちがあります。カーネルはあくまでシンプルに、完全に予測可能な動作だけをするべし……。
とはいえ、それでは実在のUnixは完全にテキスト表現から完全に独立だったかと言うと、まあ"/"の例もあるように、実際にはそうではないわけで。いわばUnixは「ASCIIとその拡張文字集合およびASCIIと矛盾しない文字符号系」を暗黙に仮定していたとも言えます。だとすると、この暗黙の制限を、より強く明示的にして、その強い制限の下ですべてのアプリケーションを書くことにするのも、Unixの延長としてはあながち不自然ではないのかもしれません。そういう意味では、例えば元コメントのように、
> UTF-8とかで、NULLと/を含まない文字列を許す
とかはアリなのかもしれません。これならば、アプリケーションがUTF-8として作ったファイル名というバイト列を、カーネルはそのままファイルシステムに格納すれば良いだけだからです。これがUnix的思想の自然な拡張として有り得る形であるという 証拠に、元々のUnix開発者がその後開発した(している)Plan9では、ファイルシステムはunicodeで統一されていると聞いています。(それにしても「何もunicodeでなくてもいいじゃないかぁ!」というanti-unicode派としての叫びはおいておいて……)
何が言いたかったかと言うと、カーネルは暗黙の文字変換なんてせずに、あくまでアプリケーションの言うがままのバイト列を生のまま扱うことに徹するべきだと私は思う、ということです。そのためには、アプリケーションが(localeなどの)それぞれの解釈でファイルシステムを見るのは、別におかしなことではないが、それが嫌ならすべてのアプリケーションが(unicodeなどの)同一の解釈でファイルシステムを見ることに決めてしまっても良い、と。
もっとも、ドラスティックな変更を避け、簡便に使うという目的にあっては、ファイルシステム自体がlocaleを持つという仕組みを否定するものではありません。また、最後ついでに言うと、Plan9みたいに統一するにしてもunicode
ただ、ファイルシステムにファイル名を書き込むなら、そのファイルシステムでサポートするコーディングで格納するべきで、ロケール設定に従うのはちょっと変かなと思う。
Windows NT/NTFS とかだと, ディスクに格納されるファイル名は Unicode で, かつプロセスが非 Unicode エンコーディングを使う場合に何を使うかという情報がプロセスの属性としてあるので,ファイル操作システムコールでファイル名としてどの文字エンコーディングが渡されるかが判定できます。それに対して UNIX の場合,「プロセスがファイル名文字列をどの文字エンコーディングで渡してくるか」という情報をカーネルレベルでもっていないので,変換しようにもできない。 (ロケール処理はライブラリレベルで実現されていて, カーネルレベルでは認識されていないので。)
NFS とか FAT ファイルシステムとかのマウントのときに, 文字エンコーディングを指定できるようにした処理系もありますが, これは,どちらかといえば苦し紛れの策ですからね。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
人生の大半の問題はスルー力で解決する -- スルー力研究専門家
重い (スコア:3, 興味深い)
そんなに多バイト文字つかいたいんですか?
まあ、メモリ一桁メガバイトの住人のたわごとか。
------------------------- Excess and Obsolete
Re:重い (スコア:0)
# EUC-JP と Shift_JIS が混在するとどう振る舞うんだろう (^^;;
EUC-JP と Shift_JIS が混在 (スコア:2, 参考になる)
ja_JP.SJIS ロケールでは、いわゆる半角カナも含めて、 Shift_JIS を正しく扱います。
ただし、ふつうは ja_JP.SJIS ロケールなんてのが用意されてない だろうから、localedef コマンドを使って作らないといけません。
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
bash-2.05b$ echo 表表
とかすると、2byte目の0x5cが悪さするんですが。
Just a whisper. I hear it in my ghost.
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
$ ls /usr/lib/locale/
de_DE en_US.utf8 fr_FR@euro ja_JP.sjis ko_KR.euckr
en_US fr_FR ja_JP.eucjp ja_JP.utf8 ru_RU.koi8r
$ echo $LANG
ja_JP.SJIS
$ echo 表表
表表
$ echo 表表 | od -t x1
0000000 95 5c 95 5c 0a
0000005
$
ヒストリとか、カーソル移動とか、編集も問題ありません。
Re:EUC-JP と Shift_JIS が混在 (スコア:0)
$ export LANG=ja_JP.SJIS
$ bash
$ echo 表表
表表
$ echo 噂
噂
$
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
/usr/lib/nls/loc/ あたりを修正しないと動かないのかな。
Just a whisper. I hear it in my ghost.
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
ja_JP.SJIS ロケールは,作成可能でしょうか。
最近流行の,Shift_JIS を厳密に解釈することを求める立場からすると, 0x5C のコードポイントにある文字 (\) は,Shift_JIS ではバックスラッシュ (REVERSE SOLIDUS) ではなくて円記号 (YEN SIGN) です。 そして,ISO C にしろ,POSIX にしろ,バックスラッシュのコードポイントがロケールによって動的に変わってしまう状況は想定していないはずなので, たとえ charmap ファイルは作成可能にしても, それを実際に運用するのは難しいと思います。
たとえば,0x5C の文字は Shift_JIS では円記号だからエスケープ文字ではないはずなのに,プログラムによってエスケープ文字と解釈されたり(しなかったり)するとか。もっとも
LANG=ja_JP.SJIS; export LANG
とかやったとたんに,既存のシェルスクリプトが軒並み動かなくなったりするのも困りますけどね :)
いや,もちろん,堅いことを言わなければ使えるのはわかりますよ。
CP932 (スコア:2, 興味深い)
CP932 は、日本語版 Windows で使われている文字コードで、(JIS X 02xx の世界から見れば) Shift_JIS にいわゆる「機種依存文字」を追加したものです。が、ミソは、Unicode から見たとき、Shift_JIS と CP932 はそれ以上の差異があるという点です。
それは、CP932 と Shift_JIS とでは、Unicode への変換テーブルに一部相違がある、という点です。そのひとつの例として、CP932 では、0x5c は U+005C に変換されます。ほか、JIS X 0208 に属する文字にも、いくつか相違があります。
問題は、日本語版 Windows では、U+005C は円記号だったりすることなんだけど、いまのところそれは関係ないし。
Re:CP932 (スコア:0)
> 最近流行の,Shift_JIS を厳密に解釈することを求める立場
の人に
> 既存のシステムでこの問題をてっとりばやく片付ける方法は、Shift_JIS の代わりに CP932 を使うことです。
というのは、返答としてどうかな?と思います。
それはともかく、Single Unix Specification の該当項 [opengroup.org]を読んでみましたが、
Escape Character って確かに Bac
Re:EUC-JP と Shift_JIS が混在 (スコア:0)
Unicode が絡むとまともに処理するのが難しいものの、
それをちゃんと解決できないのは実装がヘボイだけ、
というそしりを免れるものではありません。
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
とか書いたんですけど、よくよく考えてみるとそんな単純な
話でもないのかなぁ、と思い始めたりして。
どうもこの辺は実装依存の話で、Single Unix Spec あたりを見ても
厳密には書いてないのですけど、Portable charset としては確かに、
\ として reverse solidus とか backslash とか書いてあるんですよね。
一方で、伝統的な ja_JP.SJIS では、JIS X 0201 Roman は
ISO 646 の思想に従って \ を ISO 646-IRV のそれと同質に
解釈するのが普通だったりしますな。
結局、そこは実装依存という話なので、一概に言い切れない、
という話ですね。失礼しました。
Re:EUC-JP と Shift_JIS が混在 (スコア:1)
苦し紛れにそういうことをしていたのは事実ですが, それは「ISO 646 の思想」というほど 確乎としたものなのでしょうか。 ISO 646 は ASCII をもとにした符号化文字集合で, 「各国版 (National version)」として一部の文字を入れ替えた版を作ることを許してはいましたが, そのうちの入れ替えられた文字を別の National version の文字 あるいは「国際参照版 (IRV)」と同等に解釈してよいという規定はなかったと思います。
たとえば,日本版では 0x5C は「円記号」ですが, 韓国版ではこれは「ウォン記号」になります。 これを一緒にされたら困るでしょう。 貨幣価値も一桁くらい違うし :-)
Re:EUC-JP と Shift_JIS が混在 (スコア:0)
Re:重い (スコア:0)
Re:重い (スコア:1, すばらしい洞察)
所詮 filename は NULL と / を含まない バイト列。
どっかで紳士協定が無いとね…
Re:重い (スコア:1)
ただ、ファイルシステムにファイル名を書き込むなら、そのファイルシステムでサポートするコーディングで格納するべきで、ロケール設定に従うのはちょっと変かなと思う。
実際は、"UTF-8とかで、NULLと/を含まない文字列を許す(制御文字はダメだけど)"ほうが現実的ですよね。(問題起こしにくいですよね)
# 当たり前なのかな
# 変なこと言ってる?
M-FalconSky (暑いか寒い)
カーネルの基本は「無変換」であるべし教 :-) (スコア:3, 興味深い)
これはこれで納得できる考え方ではあります。普通に現実的解法を求めるなら、ほとんど必然的結論とすら言えるかもしれません。
とはいえ、UNIXといえば昔から、カーネル内ではなるべくテキスト表現の方法に依存せず、単なるバイト列として生のまま処理しようとするところに特徴があったという考えもできます。例えばファイルの中身はある長さを持つバイト列というだけあって、カーネルはそれが「80文字レコード」だの「可変長文字レコード」だのといった構造を持っているかどうかは関知しません。UnixやWindowsなどはその点で同じ特徴を持っていますが、そうでないOSもあります。UnixとWindowsでは改行文字が違うと言われることもありますが、それはOSが何か改行文字を特別扱いしているというわけではなくて、それぞれのアプリケーションが特定のバイト列をどう改行と見なすかというだけの違いで、実はアプリケーション毎に異なった扱いでも(OSから見れば)構いません(少なくともUnixでは。Windowsではもしかすると特別扱いがあるのかもしれませんが、寡聞にして知りません)。
ファイル名にしても同様で、伝統的Unixではディレクトリ中のファイル名は(必要ならNULで終端した)14バイト以内(その後もっと長くできるよう拡張された)の列と決まっていただけでした。ファイルシステム自体は、NULだけは特殊な意味を持っていたものの、あとは長さの制限だけしか持っておらず、それを守る限りは、アプリケーションが、ファイル名自身バイナリ列であるようなファイルを使っても、OSは気にしません(ただしカーネル内のnamei()関数が"/"を特別扱いするために、NULに加えて"/"も特別扱いになっています。これは、個人的にはUnixの齟齬の一つと思います)。
しかしファイルシステムにlocaleを持ち込んでしまうと、アプリケーションの指定したファイル名というバイト列が、暗黙の内に別のバイト列に変換されてしまうわけで、これはせっかくの「単なるバイト列」という特徴を崩してしまう気がします。極端な話アプリケーションがファイル名自体がバイナリであるようなファイルを作る場合、あるlocaleの下では同一ではあっても、バイト列としては異なるファイル名に変換されてしまい、アプリケーションが不具合を起こすということもあるでしょう。(まあ、そんな変なファイル名をつける方が悪いというのは常識的には正しい指摘なのですが。)
そういったわけで、私の個人的感情としては、Unixカーネルはあくまですべてを単なるバイト列として扱い、そこにテキスト表現を見いだすのはアプリケーションレベル以上だけにして欲しい、という気持ちがあります。カーネルはあくまでシンプルに、完全に予測可能な動作だけをするべし……。
とはいえ、それでは実在のUnixは完全にテキスト表現から完全に独立だったかと言うと、まあ"/"の例もあるように、実際にはそうではないわけで。いわばUnixは「ASCIIとその拡張文字集合およびASCIIと矛盾しない文字符号系」を暗黙に仮定していたとも言えます。だとすると、この暗黙の制限を、より強く明示的にして、その強い制限の下ですべてのアプリケーションを書くことにするのも、Unixの延長としてはあながち不自然ではないのかもしれません。そういう意味では、例えば元コメントのように、
とかはアリなのかもしれません。これならば、アプリケーションがUTF-8として作ったファイル名というバイト列を、カーネルはそのままファイルシステムに格納すれば良いだけだからです。これがUnix的思想の自然な拡張として有り得る形であるという 証拠に、元々のUnix開発者がその後開発した(している)Plan9では、ファイルシステムはunicodeで統一されていると聞いています。(それにしても「何もunicodeでなくてもいいじゃないかぁ!」というanti-unicode派としての叫びはおいておいて……)
何が言いたかったかと言うと、カーネルは暗黙の文字変換なんてせずに、あくまでアプリケーションの言うがままのバイト列を生のまま扱うことに徹するべきだと私は思う、ということです。そのためには、アプリケーションが(localeなどの)それぞれの解釈でファイルシステムを見るのは、別におかしなことではないが、それが嫌ならすべてのアプリケーションが(unicodeなどの)同一の解釈でファイルシステムを見ることに決めてしまっても良い、と。
もっとも、ドラスティックな変更を避け、簡便に使うという目的にあっては、ファイルシステム自体がlocaleを持つという仕組みを否定するものではありません。また、最後ついでに言うと、Plan9みたいに統一するにしてもunicode
Re:重い (スコア:2, 参考になる)
Windows NT/NTFS とかだと, ディスクに格納されるファイル名は Unicode で, かつプロセスが非 Unicode エンコーディングを使う場合に何を使うかという情報がプロセスの属性としてあるので,ファイル操作システムコールでファイル名としてどの文字エンコーディングが渡されるかが判定できます。それに対して UNIX の場合,「プロセスがファイル名文字列をどの文字エンコーディングで渡してくるか」という情報をカーネルレベルでもっていないので,変換しようにもできない。 (ロケール処理はライブラリレベルで実現されていて, カーネルレベルでは認識されていないので。)
NFS とか FAT ファイルシステムとかのマウントのときに, 文字エンコーディングを指定できるようにした処理系もありますが, これは,どちらかといえば苦し紛れの策ですからね。