PowerShellの分かりにくいところに、パイプラインの途中で文字エンコードの変換が入り、これが直接はユーザーに見えないことから、文字エンコードを調べると奇妙な結果が出てしまう、場合によっては文字化けすることがある。

実は、こうした問題は、非英語環境独特の問題である。
話がややこしくならないように、ここでは、すべて下記の条件を満たした日本語環境であることを前提とする。

・「コントロールパネル ⇒ 地域 ⇒ 管理 ⇒ Unicode対応ではないプログラムの言語」が「日本語(日本)」
・「設定 ⇒ 時刻と言語 ⇒ 言語と地域 ⇒ Windowsの表示言語」が「日本語」

なお、評価は、Windows 11 Ver.25H2 OSビルド26200.8655の上で、PowerShell Ver.7.6.3、Windows PowerShell Ver.5.1.26100.8655、cmd.exe Ver.10.0.26100.8521を使って行った。

簡単にいうと、PowerShellは、外部コマンド(実行ファイルを持つコマンド)をパイプライン内で起動するとき、$OutputEncodingで指定された文字エンコードを使って文字列を渡す。また、外部コマンドの実行環境のコードページを$OutputEncodingと同じにする。

PowerShellは、外部コマンドにパイプラインで情報を渡すときには、MS-DOSなどと同じく、標準入出力を使い、テキストで情報を渡す。このときに問題になるのが、文字エンコードである。これは、PowerShell内では、$OutputEncodingという変数を使って制御する。この変数に設定されたエンコーダーやコードページが使われる。なお、この動作は、ファイルへの書き込み、読み出しとは無関係である点には注意されたい。

もう1つ、PowerShellの実行環境には、コンソール出力、入力がどの文字エンコードで行われるのかを設定する設定値がある。それは、“[System.Console]::OutputEncoding”と“[System.Console]::InputEncoding”である(Systemは省略可能)。$OutputEncodingと合わせ、Windows PowerShell 5.1およびPowerShell 7.6.3の初期値を表01に示す。


コマンド出力の文字化けとしては、これら3つの設定値に起因するものが多い。簡単にいうと、PowerShellが出力したテキストの文字エンコードと、“[Console]::InputEncoding”が一致していなければ文字化けが起こる。マイクロソフトのサイトによれば、PowerShell、Windows PowerShellでは、$OutputEncodingと、[Console]::InputEncodingは、値を合わせる(同じエンコーダーを設定する)必要があるという。

・about_Preference_Variables - PowerShell

しかし、日本語環境では、デフォルトの設定値が一致していない。筆者は、テキストファイルは、すべてUTF-8を使うことにして、シフトJISを捨てた。なので、この3つをすべてUTF-8に設定している。PowerShell 7.xならば、プロファイル内で

[Console]::OutputEncoding = [Console]::InputEncoding = $OutputEncoding

とする。Windows PowerShellの場合は、

[Console]::OutputEncoding = [Console]::InputEncoding = $OutputEncoding = [System.Text.Encoding]::UTF8

とする。

今回のタイトルネタは、ケイト・マスカレナス(Kate Mascarenhas)の「時間旅行者のキャンディボックス」(創元SF文庫。原題 THE PSYCHOLOGY OF TIME TRAVEL , 2018)である。タイムトラベルは、物理学的には大難問なのだが、なんだか、コンピュータの開発みたいにできちゃう反面、時間と人間に関わる話に重点が置かれている。
編集部おすすめ