Windows OSのコマンドとLinuxのコマンドを連結して処理する場合、気になるのが文字コードの扱いであろう。例えばファイル名やフォルダ名などが日本語の場合、その一覧をWSL上でファイルに保存すると文字コードは何になるのか? そのファイルの内容をWindows側コマンドで(リダイレクトなどで)読み出すと、どういう文字コードのデータが渡されるのか? そのあたりを見てみよう。
先に結論を述べておくと、WSL環境では文字コードは全て「UTF-8」になっていて、WSL上から呼び出したWindowsプログラムにも、UTF-8でテキストが渡されることになっている。
Linuxに限らず、ITやインターネットの世界では最近はUTF-8(=汎用文字コードである「Unicode」をバイトストリームとして扱うための符号化方式)が主流であり、WSLがUTF-8を使っていても何ら不思議ではないし、問題ではない。
だが日本語Windows OSでUTF-8を使うとなると、少し問題が起こる可能性がある。日本語Windows OSの場合、その前身であるMS-DOSの時代からシフトJISコードが標準として使われているからだ。
日本語Windows OSの文字コードを見ると次のようになっている。chcpはコードページ(=Windows OSにおける言語設定セットの番号のこと)を表示したり、変更したりするコマンドである。
コードページ番号=932は、シフトJISを表す番号である。コードページ番号を切り替えると、日本語と英語などを切り替えることができる(TIPS「jp、usコマンドを利用する」参照)。
次は、WSLからコマンドプロンプトを呼び出して、そのコードページを調べてみよう。
いずれもコードページ番号=65001(UTF-8)となっていることが確認できる。
コードページがUTF-8になっていてもWindows OSのコマンドは動作するが、場合によっては結果が異なることがある。具体的には例えばdirコマンドなら、日本語で「ドライブ C のボリューム ラベルは WINDOWS10 です」と表示されていたものが、「Volume in drive C is WINDOWS10」のように英語メッセージになる。
WSLの言語設定とコードページの関係を図にすると、次のようになっている。
Linux側の言語設定(ロケール)を確認したり、変更したりする方法についてはTIPS「Windows 10のBash on Windowsのロケールを英語モードに切り替える」を参照していただきたい。
Windows OS日本語表示がUTF-8とはどういうことか、もう少し詳しく見てみよう。
まずWindowsのコマンドプロンプトを開いて次のコマンドを実行してみる。
※以下で利用している「jhd.exe」は、16進数でダンプするWindows向けのコマンド、「nkf -g」は文字コードを判定するコマンドである(TIPS「nkfツールで文字コードを変換する」も参照)。同等の機能を持つプログラムなら何でも可。
いずれもシフトJIS(コードページ=932)になっていることが分かる。
次はこのコマンドを、WSL(Ubuntu)上で実行してみる。
※od -t x1zは16進数でダンプするLinuxの標準コマンド。nkfは、Ubuntuなら「sudo apt install nkf」で導入できる。
このように文字コードはUTF-8になっている。
次は、WSL上からWindows OS側のコマンドを呼び出して実行してみる。
これから分かるように、Windows OS側のjhd.exeやnkf.exeには、シフトJISではなく、UTF-8で文字コードが渡されている。さらによく見ると、改行コードもWindows OS流の「0D-0A(CR-LF)」ではなく、Linux流の「0A(LF)」のみとなっている。
逆に、Windows OS側のコマンドの実行結果をWSL側に渡すと次のようになる。
この場合は逆に、LinuxのコマンドにシフトJISの文字とWindows流の改行コードが渡されている。そのため、漢字文字の部分は正しく表示できなくなっている(コマンドプロンプトのコンソール設定はシフトJIS)。
以上をまとめると、次のようになっている。
もう1つ付け加えておくと、WSLのコンソールウィンドウはUTF-8に対応しているが、少なくとも現状のバージョンでは、UnicodeのBMP以外の文字(U+10000〜U+10FFFFにある、サロゲートペアの対象となる領域の文字)を表示することはできない(コマンドプロンプトウィンドウでも同様に表示できない)。これらの範囲のUnicode文字を利用したい場合は注意が必要だ(メモ帳やワードパッドなら表示できる)。
Windows OSのコマンド、特に日本語を扱うようなコマンドは、従来はほとんどの場合、シフトJISのみを対象としてきた。そのため、UTF-8の文字コードを渡されても正しく処理できないことが少なくない。
最近ではインターネットを中心にUTF-8が普及しているので、UTF-8に対応しているプログラムやシステムも増えてきている。パイプやリダイレクトの処理では、文字コード(および改行コード)は変換されないので、シフトJISのデータとして入出力したい場合は、文字コードをシフトJISに変換してから処理したり、保存したりするなどの対応が必要になるだろう。
なお、Windows OS側の文字コードをシフトJISではなく、UTF-8に統一するという方法もある。具体的にはコマンドプロンプト上で「chcp 65001」を実行する。だがこの設定を行うと、メッセージが英語になるだけでなく、今度はUTF-8のテキストしか表示できなくなる(シフトJISのテキストをtypeやmoreコマンドで表示できなくなる)。プログラムによってはシフトJISにしか対応しておらず、文字化けになったり、文字の検索や置換処理などが行えなくなったりするものも少なくない。このように、コンソール画面をUTF-8にする方法は、実用上問題が多い。
今回はWSLからWindows OSのコマンドを呼び出す方法や、その上で日本語テキストを扱う場合の文字コードの問題について見てきた。
WSLではLinux系のツールなどがそのまま使えるので、テキストデータ整理などにも活用したい、と思うだろうが、その場合は文字コードをどうするかについても考えておく必要がある。ただしこれはWSL固有の問題ではなく、複数の文字コードが混在したシステムや環境では常に考慮すべき事項である。シフトJISかUTF-8のどちらかに統一することになるが、現実的な利用シーンや今後の活用のことなどを考えると、なるべくUTF-8を使うことになるだろう。
Copyright© Digital Advantage Corp. All Rights Reserved.