Windows 10でUbuntuのシェル「Bash」が動き始める! だが日本語はどうなる?:Windows 10 The Latest(2/2 ページ)
Windows 10にLinuxサブシステムが実装され、UbuntuのBashが利用できるようになるという。その用途や仕組みは? 日本語に関するWindowsならではの宿命的課題にも触れる。
Bashを使ってみる
このBashはリリースされたばかりのβ版であり、まだまだ使えない機能やコマンドも多い。基本的にはコマンドラインでのみ使うことを前提としており、GUI系のツール(X Window Systemを使うもの)はサポートされていない。
そのため、想定される用途はあまり多くなく、例えばコマンドラインツール(コンパイラやリンカなど)を使ったプログラム開発や、文字列処理ツール(grepやsed、awkなど)を使ったテキスト処理、ファイル整理などが考えられる。
Bash上でコンパイルする例
Bash上でプログラムをコンパイルする例。gccはデフォルトではインストールされていないので、あらかじめapt-getでgccをインストールしておいた。
(1)パッケージのインストールコマンドの例。通常のUbuntuの手法がそのまま使える。
(2)Hello worldプログラムをコンパイルしてみる。
(3)実行してみる。
(4)実行ファイルを確認してみる。LinuxのELFファイルをそのまま実行している。
デフォルトではコマンドが不足しているものの、Ubuntuと同様に、apt-getコマンドで新しいツールなどを簡単にオンラインで追加インストールできる。Ubuntuの利用経験があるユーザーなら使うのも容易であろう。
Bash on Ubuntu on Windowsでは、最終的にはUbuntuのバイナリファイルが全てそのまま動作することを目標としている。だが現状ではまだ機能が不足しており、まったく動かなかったり、画面表示が乱れたりすることも少なくない。moreやviはほぼ動くが、lessは逆スクロールがうまくできなかったりする。また、エミュレーションの機能の不足により、例えばtopコマンドはまったく動作しない(/devや/procを参照するようなツールは動かないものが多い)。あと、日本語はなんとか表示できるものの、編集はかなり難しい(文字が半分だけ消えたり、画面表示が部分的に崩れたりする)。このあたりは、今後の改善を期待しよう。
Bashの用途は?
Bash on Ubuntu on WindowsではUbuntuのBashが動作しているため、キャラクタベースの(GUIのない)Ubuntuコンソールのようなものと考えるかもしれない。
だがMicrosoftは、サーバ的な用途、すなわち WebサーバやDBサーバなどの実行基盤にも向かないとしている(そういう用途には使わないで欲しい、とのこと)。
UNIX/Linux環境が利用できるようになったというよりは、クライアント用途向けのキャラクタベースの新しいシェル実行環境が追加された、と見るべきだろう。つまり、コマンドプロンプトやWSH、PowerShellの代わり、という位置付けである。
本格的にLinux/Ubuntuを使いたければ、Hyper-Vのような仮想環境の上にUbuntuを載せて運用した方が、よほど高速、快適である。昨今では開発系でもGUIのツールを使うのが一般的なので、このBash on Ubuntu on WindowsをLinuxのつもりで使うと期待を裏切られるかもしれない。Windowsではできないこと、やりにくいことを解決するために補助的に使うのがよいと思われる。
Bashが動作する仕組み
Windows上でUNIXやLinuxのコマンドを実行する環境と言えば、今までにも幾つもあった。もともとWindows OSには「POSIX(Portable Operating System Interface based on UNIX)」や「Interix」というUNIX APIをサポートするサブシステムが実装されており、それを使った「SFU(Windows Services for UNIX)」や、その後継の「SUA(Subsystem for UNIX-Based Application)」があった(TIPS「UNIX互換環境を実現するSUAを利用する」参照)。
POSIX/InterixサブシステムがサポートするAPIは、現在のUNIX/Linuxと比較すると機能が不足しており、UNIX向けのさまざまなツールなどをそのまま動作させることはできない。SFU/SUA向けに改修が必要であり、そのため利用できるプログラムはあまり多くなかった。また、これらのサブシステムはWindows 8.1/Windows Server 2012 R2では廃止され、利用できなくなっている。
これに対して、POSIX/Interixサブシステムを使わずにUNIX互換の実行環境を提供しようとするプロジェクトも幾つかあった。それが「Cygwin」や「MSYS(Minimal SYStem)」である*1。これはPOSIX/InterixサブシステムよりもUNIXとの互換性が高く、現在でもよく使われている。ただしバイナリが用意されていないツールを使うには、CygwinやMSYS向けにコンパイルする必要がある。
*1 連載「こっそり始めるGit/GitHub超入門」で紹介されている「Git for Windows」もこのMSYSベースのツールである。今すぐgitコマンドを使いたいなら、このBashを待つよりも、Git for Windowsを導入した方が簡単だ。gitコマンド以外に、シェルやgrepなどのツールも含まれている。TIPS「【総まとめ】Windowsコマンドプロンプトの入門から使いこなしまでの記事」も参照。
今回の新しいBash on Ubuntu on Windowsは、これらのプロジェクトと比較すると、より野心的である。現在流通している64bit版Ubuntu向けのELFファイル(Linuxの実行形式のファイル)を「そのまま」Windows 10上で実行できることを目指しているからである。apt-getコマンドでUbuntu向けのパッケージを持ってくればそのまま実行できるし、当然Ubuntu向けのソースコードも修正なしにコンパイルして実行できるはずである。
この仕組みは、仮想マシン上でLinuxを動かしている訳ではないので、Linuxシステム全体を稼働させるというオーバーヘッドはない。また、Dockerのようなコンテナ技術を使ってLinuxのプロセスを稼働させている訳でもない。
これを実現するために、LinuxのAPIをエミュレーションする機能「Windows Subsystem for Linux(WSL)」がカーネルに追加されている。実際のファイル名は「%windir%\System32\Drivers」にある「lxcore.sys」と「lxss.sys」の2つである。
Windows 10におけるLinux APIのエミュレーション
Build 2016のセッション「Running Bash on Ubuntu on Windows!」の資料スライドより引用。LinuxのAPIをエミュレーションすることにより、さまざまなLinux向けのプログラムを実行できるようになる。以前のPOSIXサブシステムは、Windows OSのサブシステム(OSカーネルと密接に連携して動作するモジュール)として実装されていた。しかし今回はサービス(LxssManagerサービス)として実装されているようである。
Linuxのシステムコールは現在300個以上ある。そのそれぞれについて、Ubuntuと同じ挙動になるように解釈するのがエミュレーションレイヤーの役割である。
例えばLinuxのプログラムからファイル「/usr/include/stdio.h」を「open」しようとすると、Windows上ではLinuxのルートフォルダ(「%userprofile%\AppData\Local\Lxss\rootfs」)から「usr」「include」「stdio.h」とパスをたどってファイルをオープンするという処理を実行する。Linuxにはシンボリックリンクや「/proc」「/dev」「/mnt/c/〜」(ここにはWindows側のC:ドライブがマップされている)のような仮想ファイルもあるし、属性やユーザーIDの解釈なども異なるため、パスを1段ずつ解釈する必要がある。
なおこのBashでは、(現状では)Windowsのアプリケーションを起動したり、パイプでWindows側のツールにデータを渡したりすることはできず、Bash環境はユーザーごとに閉じている。また、グラフィックスデバイスもサポートされていないので、X Window Systemを動作させることもできない。ただし「MinGW」などでX Window Systemを起動しておいて、そこへ接続する、クライアントアプリケーションなら動作可能である。
日本語はUTF-8のみサポート?
前述した今までのUNIX互換環境が、実は日本ではいまひとつ活用しづらい理由があった。日本語文字コードと日本語ファイル名の問題である。
Windowsのコンソール(コマンドプロンプト)やWindows系のアプリケーションでは、日本語はShift_JISコードで扱うのが一般的である(Windows OSの内部では「Unicode」だが、入出力時にShift_JISに変換されている)。現在のWindowsでは日本語のファイル名やフォルダ名が当たり前のように使われているので、「dir > file.txt」などとすると、Shift_JISコードのファイルになる。バッチやスクリプト中でも、日本語の文字列やコメントを使うのは当たり前だ。
ところがこのBashでは、漢字コードは「UTF-8」になっている。Bashのウィンドウのプロパティを見ても、コードページは「65001(UTF-8)」となっており、「ls > filelist.txt」で作成したテキストファイルは(BOMなしの)UTF-8になっている。今どきのUNIXやLinuxかいわいでは、UnicodeやUTF-8を使うのが当たり前だから(環境を問わず、日本語も英語もその他の言語も同時に扱えるようになる)、これは当然だろう。
Bashのプロパティ画面のコードページ表示
Bashのコンソールウィンドウを表示しているアプリケーションは、コマンドプロンプトのアプリケーションとほぼ同じように見える(プロパティ画面が同じ)。
(1)Bashの文字コードはUTF-8。一方、コマンドプロンプトはShift_JIS(日本語版Windows OSでのデフォルト)と、この点だけが異なる。
となると、気になるのが従来のShift_JISを使ったファイルや処理手順との互換性の問題である。UNIX/Linuxのツールを使えば、テキスト処理も高度なスクリプトによる自動処理で簡単といわれる。だが、漢字コードの違いで、LinuxのコマンドとWindowsのコマンドを組み合わせて使う場合はいちいちコード変換をしなければならないなど、注意が必要である(これはWindowsのせいではないのだが)。
ちなみにPowerShellでは、(コマンドレットにもよるが)リダイレクトして作成したファイルの漢字コードはUnicode(BOM付きのUTF-16LE)になり、パイプでWindowsのコマンドに渡すとShift_JISコードで渡されるので、さらに話が面倒になっている。
日本語ファイル名と文字コード
このBash(コンソール)の日本語文字(というか英字以外のUnicode文字)サポートはまだ完全ではなく、表示が乱れることがよくある。viやemacsなどではもっと激しく表示が崩れるが、そのうち改善されるだろう。がそれよりも、さまざまな日本語文字コードが混在することによる混乱の方が心配だ。
(1)日本語のフォルダの例。「新しいフ」と表示されているが、実は後ろの方が切れている。まだ正しく表示されないようだ。
(2)本当は「新しいフォルダー」が正しい。
(3)Bash上で標準出力をファイルにリダイレクトしてみる。
(4)各ファイルの内容をfileコマンドでチェックしてみる。上から順に、今Bash上で作ったファイル、Windowsのメモ帳で保存したファイル、PowerShell上でリダイレクトして作ったファイル、Windowsのdirコマンドでリダイレクトして作ったファイル(Shift_JISファイル)。このようにWindows上だといろいろな文字コードが使われている。
筆者は、ここでBashのデフォルト出力もShift_JISにしろと要望するつもりはない。むしろコマンドプロンプトのデフォルト文字コードやコマンド群をそろそろ全部UTF-8対応にして欲しいくらいだ(ただしメッセージ表示は日本語のままで。現在のコマンドプロンプトでコードページをUTF-8にすると、メッセージが全部英語になってしまう)。Unicodeの方が文字数が多く、Shift_JISでは表現できない文字も多くあるし、Web系を中心に現在ではUTF-8を使う開発手法が広く普及しているので、もはやShift_JISを一刻も早く止めたいと誰もが考えているだろう。だがそんなことをすると、既存のバッチファイルやテキストファイル、スクリプトなどが互換性問題を起こす可能性があるので、当然そんなことは簡単にはできない。悩ましい限りである。
Windows 10のBashサポートは、2016年夏に公開されるWindows 10のAnniversary Update to Windows 10版で正式に追加される予定である。その時には、もっと完成度が向上しているであろう。一度は廃止されたUNIX互換環境だが、まさか強化されて戻ってくるとは思わなかった。Windows 10ではコマンドプロンプトも強化されるなど(TIPS「【まとめ】Windows 10で強化/追加されたコマンドプロンプトの機能」参照)、今コマンド周りが熱い(かもしれない)。
Copyright© Digital Advantage Corp. All Rights Reserved.