結論
Windows PowerShellとPowerShellとで、リダイレクトした際に出力ファイルのエンコーディングが違っていることを知ったので、記事として記録を残しておきたいと思います。詳細は下記の通りです。ついでにコマンドプロンプトも調べました。
シェル | 出力ファイルのエンコーディング |
---|---|
PowerShell(pwsh) | UTF-8(BOMなし) |
Windows PowerShell(powershell) | UTF-16(LE) |
コマンドプロンプト(cmd) | Shift_JIS |
改行コードはすべてCR+LFです。
経緯
筆者は普段、Windows PCではPowerShell 7.2を利用しています。ご存知とは思いますが、PowerShell(旧称: PowerShell Core)は、オープンソースかつマルチプラットフォームなシェルで、Windowsに付属している、Windows PowerShell 5.1とは別物となっています。Windows PowerShellはその名の通りWindows専用で、もはや機能追加はされずにメンテナンスのみの状態となっています。
たまたま、Windows PowerShellしかない環境で作業をする機会があり、以下のようなエラーに遭遇しました
(一部の情報は省略しています)
PS C:\tmp> echo '{ ... }' > package.json
PS C:\tmp> npm install
npm ERR! code EJSONPARSE
npm ERR! path C:\tmp/package.json
npm ERR! JSON.parse Unexpected token "�" (0xFFFD) in JSON at position 0 while parsing "..."
npm ERR! JSON.parse Failed to parse JSON data.
npm ERR! JSON.parse Note: package.json must be actual JSON, not just JavaScript.
package.jsonを開いたところ、エンコーディングがUTF-16(LE)だったのが分かりました。
その後気になったので、Windows系のシェルでリダイレクト自のエンコーディングを調べ、先述の通りの結果が得られました。調査中、バイナリはhexdump for VSCodeで見ました。わざわざバイナリエディタをインストールしなくてもよいので便利でした。
Windows PowerShellでUTF-8出力するには、以下のようなコマンドを利用することも可能です。1行目のコマンドは上書きで、2行目のコマンドは追記です。
echo '{ ... }' | Out-File -Encoding utf8 package.json
echo '{ ... }' | Out-File -Encoding utf8 -Append package.json
しかし出力結果は、BOM付きUTF-8となってしまうので、素直にPowerShell 7.2を利用することをお勧めします。ちなみに本来UTF-8にBOMは必要ありません。MicrosoftがASCIIとUTF-8とを区別するために、オレオレ仕様で付けるようにしたようです。