はじめに
Windows10のコードページについて、デフォルト(Shift_JIS)の932
とUTF-8の65001
との動作の違いが良くわからなかったので、調べてみたメモです。
結論
cmd
でコードページを65001
にすると
- コマンドの実行結果が英語表示になる
-
type
してリダイレクトしても文字エンコードは変わらない - PowerShell経由でShift_JISを表示させて、その結果をリダイレクトすると、BOMなしUTF-8に変換される
PowerShellでは
- デフォルトの
932
では、外部コマンドの実行結果も日本語で統一される - デフォルトで
65001
に切り替えると、外部コマンドの実行結果が英語表示になる - コンソール出力をUTF-8にすると、外部コマンドの実行結果が英語表示になる
WSLからWindowsのコマンドをパイプラインで使うと
- コードページが
65001
に切り替わって、その実行結果がWSLに渡される
試したこと
コマンドシェル(cmd)
コマンドプロンプトとかコマンドウィンドウと呼ばれていますが、コマンドシェル(Command shell)というのが正式な名称1のようです。
デフォルト
C:>chcp
現在のコード ページ: 932
C:>dir \ | findstr C:
C:\ のディレクトリ
コマンドの実行結果が日本語で表示されます。
chcp 65001
の後
Active code page: 65001
C:>dir \ | findstr C:
Directory of C:\
コマンドの実行結果が英語になっています。
このままリダイレクト結果を確認してみます。
入力ファイルの確認:テスト用ファイルをtype
C:>type utf8.txt
これはUTF-8のテキストです。
C:>type utf8bom.txt
これはBOM付きUTF-8のテキストです。
C:>type sjis.txt
SJIS�̃e�L�X�g�ł��B
C:>powershell -c cat sjis.txt
SJISのテキストです。
HTMLの中では実行結果が同じに見えるかもしれませんが、BOM付きのファイルをtype
すると、行頭に・
(半角の中点)が表示されます。
テスト用ファイルをtype
してリダイレクト
C:>type utf8.txt >cmd_cp65001_type_utf8.txt
C:>type cmd_cp65001_type_utf8.txt
これはUTF-8のテキストです。�
C:>type utf8bom.txt >cmd_cp65001_type_utf8bom.txt
C:>type cmd_cp65001_type_utf8bom.txt
これはBOM付きUTF-8のテキストです。
C:>type sjis.txt >cmd_cp65001_type_sjis.txt
C:>type cmd_cp65001_type_sjis.txt
SJIS�̃e�L�X�g�ł��B
C:>powershell -c cat cmd_cp65001_type_sjis.txt
SJISのテキストです。
リダイレクトしても、文字エンコードは変わりません。
テスト用ファイルをPowerShellでcat
してリダイレクト
C:>powershell -c cat sjis.txt > cmd_cp65001_ps_cat_sjis.txt
C:>type cmd_cp65001_ps_cat_sjis.txt
SJISのテキストです。
C:>powershell -c "fhx cmd_cp65001_ps_cat_sjis.txt | %{$_.ToString()}"
00000000 53 4A 49 53 E3 81 AE E3 83 86 E3 82 AD E3 82 B9 SJISã®ããã¹
00000010 E3 83 88 E3 81 A7 E3 81 99 E3 80 82 0D 0A ãã§ãã..
Shift_JISがBOMなしUTF-8に変換されました。
PowerShell
デフォルト
PS > chcp 932
現在のコード ページ: 932
PS > dir \ | oss | sls c:
ディレクトリ: C:\
PS > [console]::OutputEncoding.CodePage
932
PS > cmd /c dir c:\ | sls c:
c:\ のディレクトリ
デフォルトでchcp 65001
の後
Active code page: 65001
PS > dir \ | oss | sls c:
ディレクトリ: C:\
PS > [console]::OutputEncoding.CodePage
932
PS > cmd /c dir c:\ | sls c:
Directory of c:\
外部コマンドでは、chcp 65001
で設定したアクティブコードページが使われています。
utf-8環境
PS > chcp
現在のコード ページ: 932
PS > [console]::OutputEncoding = [Text.Encoding]::UTF8
PS > chcp
Active code page: 932
PS > dir \ | oss | sls c:
ディレクトリ: C:\
PS > [console]::OutputEncoding.CodePage
65001
PS > cmd /c dir c:\ | sls c:
Directory of c:\
外部コマンドでは、アクティブコードページではなく、[console]::OutputEncoding.CodePage
の65001
が使われています。
utf-8環境でchcp 65001
の後
PS > chcp 65001
Active code page: 65001
PS > [console]::OutputEncoding.CodePage
65001
PS > dir \ | oss | sls c:
ディレクトリ: C:\
PS > cmd /c dir c:\ | sls c:
Directory of c:\
PowerShellの内部コマンドは、chcp
で設定されるアクティブコードページには依存しない、という結果だと思います。
WSLのbash
デフォルト
$echo $SHELL
/bin/bash
$chcp.com
現在のコード ページ: 932
$cmd.exe /c chcp
現在のコード ページ: 932
$cmd.exe /c chcp | cat
Active code page: 65001
表示させるだけとコードページはそのままですが、結果をパイプラインに渡すとコードページが65001
に変更されてしまうようです。Shift_JISがパイプラインに渡されると、WSL側では普通に処理できないから、自動で切り替えているようです。
デフォルトでchcp.com 65001
の後
Active code page: 65001
$chcp.com
現在のコード ページ: 932
$cmd.exe /c chcp
現在のコード ページ: 932
$cmd.exe /c chcp | cat
Active code page: 65001
コマンド実行後のメッセージは英語になりますが、実際の動作は何も変化していません。(当然の結果)
確認環境
- Windows10 Home 21H2
- PowerShell 5.1
- WSL1 Ubuntu 18.04
OS 名: Microsoft Windows 10 Home
OS バージョン: 10.0.19044 N/A ビルド 19044
PSVersion: 5.1.19041.1320
NAME STATE VERSION
* Ubuntu-18.04 Running 1
参考