分享幾個在Windows 與Linux 常見的編碼問題與解決方案

文章推薦指數: 80 %
投票人數:10人

看到上述這麼多支援的編碼不同,而跙Windows PowerShell 5.1 以前的版本竟然沒辦法指定UTF8 (No BOM) 的輸出,實在母湯!👎. ←使用luit完美解決WindowsSubsystemforLinux顯示Big5字集的問題 使用VisualStudioCode開發Java應用程式的環境設定指南→ 我每隔幾年我就會遇到一次non-Unicode的編碼問題,真的不常見,但這些年來也處理過無數次了,每次都被搞的很煩。

最近在Linux環境又遇到棘手的編碼問題,檔案內容是從ISO-8859-1(Latin-1)字集的SybaseASE資料庫轉出,所以編碼是ISO-8859-1字集,但內容其實是BIG5字集,而我用WindowsTerminal+WSL2又只支援顯示Unicode字集的文字,所以文字無法正常在螢幕上顯示或複製。

幾經嘗試後,我決定把這幾年累積的心得都寫下來,以免日後又要再花時間研究一次。

準備一個有文字編碼問題的環境 我準備了一個以BIG5編碼的文字檔案,請先在任意Windows與Linux環境下載: Linux curlhttps://blog.miniasp.com/big5-example.txt-obig5-example.txt 我這邊的Linux版本為: $lsb_release-a NoLSBmodulesareavailable. DistributorID:Ubuntu Description:Ubuntu20.04.2LTS Release:20.04 Codename:focal WindowsPowerShell Invoke-WebRequest-Urihttps://blog.miniasp.com/big5-example.txt-OutFilebig5-example.txt ❯$PSVersionTable NameValue --------- PSVersion5.1.19041.1023 PSEditionDesktop PSCompatibleVersions{1.0,2.0,3.0,4.0...} BuildVersion10.0.19041.1023 CLRVersion4.0.30319.42000 WSManStackVersion3.0 PSRemotingProtocolVersion2.3 SerializationVersion1.1.0.1 PowerShellCore ❯$PSVersionTable NameValue --------- PSVersion7.1.3 PSEditionCore GitCommitId7.1.3 OSMicrosoftWindows10.0.19043 PlatformWin32NT PSCompatibleVersions{1.0,2.0,3.0,4.0…} PSRemotingProtocolVersion2.3 SerializationVersion1.1.0.1 WSManStackVersion3.0 Windows命令提示字元(CommandPrompt) 基本上,在Windows命令提示字元環境下,編碼問題可以很輕易的透過CHCP命令(C:\Windows\System32\chcp.com)快速切換,只要你設定的字型有支援這個字集,就可以正常顯示文字在畫面上。

我的Windows10控制台的地區設定(Regionsettings)指定的non-Unicode字集為Chinese(Traditional,Taiwan),這個設定會讓你的命令提示字元預設CodePage為950,也就是俗稱的Big5編碼。

在CommandPrompt環境下,預設可以正常輸出Big5編碼的文字: 你可以透過以下命令快速切換為使用Unicode作為預設編碼: chcp65001 或是透過以下命令快速切換回預設的CP950(Big5)編碼: chcp950 Windows命令提示字元在編碼處理上一致性很高,而且切換字集很容易,不太有什麼地雷。

WindowsPowerShell與PowerShellCore的預設編碼差異 基本上PowerShell可以區分5.1以前的版本與6.0之後的版本,兩個版本對於預設字集的處理方式不同,必須認真看待,否則執行同一個PowerShellScript並不會得到相同的結果。

使用BOM(byte-order-mark)字元的差異 PowerShellScript(.ps1)本身的內容,其實也影響著PowerShell的執行結果: 比較項目 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 檔案內容使用ANSI編碼(ASCII) 會直接視為ANSI字集 會直接視為UTF8字集 檔案內容使用UTF8編碼(NoBOM) 會直接視為ANSI字集 會直接視為UTF8字集 檔案內容使用UTF8編碼(BOM) 會直接視為UTF-8字集 會直接視為UTF8字集 如果你要在PowerShellScript中使用到non-ascii字元(例如:中文字),請務必加上BOM字元,因為Windows有時候會誤判檔案字集,如果誤判為ANSI字集的話,這些文字就會亂掉,導致PowerShellScript無法正確執行。

相反的,在Linux作業系統中,如果你加入BOM字元的話,可能會導致一些未知的問題,所以建議不要加上BOM字元。

總之,你真的想用PowerShellScript來撰寫跨平台的自動化命令腳本,不要寫中文在腳本中。

我是完全不考慮在Linux使用PowerShell了啦!XD 字元編碼處理的差異 比較項目 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 預設輸出使用的編碼 UnicodeUTF-16LE utf8NoBOM 注意:基本上UTF-16以上的文字編碼,都會強制要求一定要有BOM字元,只有UTF-8可以選擇要不要加上BOM字元。

可以指定Encoding的Cmdlets 以下是包含-Encoding參數的Cmdlets清單,可以讓你用指定的Encoding處理文字: Microsoft.PowerShell.Management Add-Content Get-Content Set-Content Microsoft.PowerShell.Utility Export-Clixml Export-Csv Export-PSSession Format-Hex Import-Csv Out-File Select-String Send-MailMessage 這個-Encoding參數支援的編碼對照 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(官網有寫但不能用)(Unknown) ❌ UTF-32BEBOM ❌(官網有寫但不能用)(BigEndianUTF32) ✅(官網沒寫這項但實際上有)(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(官網有寫但不能用)(Byte) ❌ 看到上述這麼多支援的編碼不同,而跙WindowsPowerShell5.1以前的版本竟然沒辦法指定UTF8(NoBOM)的輸出,實在母湯!👎 PowerShellCore6.0之後的版本,可用的編碼比文件上寫的多出很多,你可以用以下命令查詢出當前系統可用的編碼清單: ❯[System.Text.Encoding]::GetEncodings() CodePageNameDisplayName ----------------------- 932shift_jisshift_jis 860IBM860IBM860 861ibm861ibm861 20880IBM880IBM880 862DOS-862DOS-862 863IBM863IBM863 936gb2312gb2312 864IBM864IBM864 865IBM865IBM865 866cp866cp866 21866koi8-ukoi8-u 37IBM037IBM037 869ibm869ibm869 500IBM500IBM500 10079x-mac-icelandicx-mac-icelandic 1140IBM01140IBM01140 1141IBM01141IBM01141 1142IBM01142IBM01142 20273IBM273IBM273 1143IBM01143IBM01143 1144IBM01144IBM01144 1145IBM01145IBM01145 1250windows-1250windows-1250 1146IBM01146IBM01146 1251windows-1251windows-1251 1147IBM01147IBM01147 10000macintoshmacintosh 1252windows-1252windows-1252 720DOS-720DOS-720 20277IBM277IBM277 1148IBM01148IBM01148 10001x-mac-japanesex-mac-japanese 1253windows-1253windows-1253 437IBM437IBM437 20278IBM278IBM278 1149IBM01149IBM01149 10002x-mac-chinesetradx-mac-chinesetrad 1254windows-1254windows-1254 1255windows-1255windows-1255 1361JohabJohab 1256windows-1256windows-1256 10004x-mac-arabicx-mac-arabic 1257windows-1257windows-1257 10005x-mac-hebrewx-mac-hebrew 1258windows-1258windows-1258 10006x-mac-greekx-mac-greek 10007x-mac-cyrillicx-mac-cyrillic 20924IBM00924IBM00924 28592iso-8859-2iso-8859-2 28593iso-8859-3iso-8859-3 28594iso-8859-4iso-8859-4 28595iso-8859-5iso-8859-5 28596iso-8859-6iso-8859-6 870IBM870IBM870 28597iso-8859-7iso-8859-7 28598iso-8859-8iso-8859-8 28599iso-8859-9iso-8859-9 10081x-mac-turkishx-mac-turkish 10082x-mac-croatianx-mac-croatian 874windows-874windows-874 875cp875cp875 20420IBM420IBM420 949ks_c_5601-1987ks_c_5601-1987 20423IBM423IBM423 20424IBM424IBM424 20280IBM280IBM280 1047IBM01047IBM01047 20284IBM284IBM284 20285IBM285IBM285 10010x-mac-romanianx-mac-romanian 20932EUC-JPEUC-JP 10017x-mac-ukrainianx-mac-ukrainian 29001x-Europax-Europa 737ibm737ibm737 20105x-IA5x-IA5 950big5big5 20936x-cp20936x-cp20936 20106x-IA5-Germanx-IA5-German 20107x-IA5-Swedishx-IA5-Swedish 20108x-IA5-Norwegianx-IA5-Norwegian 20866koi8-rkoi8-r 775ibm775ibm775 28603iso-8859-13iso-8859-13 20290IBM290IBM290 28605iso-8859-15iso-8859-15 20000x-Chinese-CNSx-Chinese-CNS 708ASMO-708ASMO-708 20297IBM297IBM297 10021x-mac-thaix-mac-thai 20001x-cp20001x-cp20001 20905IBM905IBM905 20002x-Chinese-Etenx-Chinese-Eten 20833x-ebcdic-koreanextendedx-ebcdic-koreanextended 20003x-cp20003x-cp20003 20004x-cp20004x-cp20004 20005x-cp20005x-cp20005 850ibm850ibm850 20838IBM-ThaiIBM-Thai 852ibm852ibm852 20871IBM871IBM871 10029x-mac-cex-mac-ce 855IBM855IBM855 21025cp1025cp1025 20949x-cp20949x-cp20949 857ibm857ibm857 858IBM00858IBM00858 20261x-cp20261x-cp20261 1026IBM1026IBM1026 20269x-cp20269x-cp20269 1200utf-16Unicode 1201utf-16BEUnicode(Big-Endian) 12000utf-32Unicode(UTF-32) 12001utf-32BEUnicode(UTF-32Big-Endian) 20127us-asciiUS-ASCII 28591iso-8859-1WesternEuropean(ISO) 65001utf-8Unicode(UTF-8) 不過WindowsPowerShell5.1以前的版本,地雷的地方還不只這些,不同的Cmdlet實作上對「預設編碼」的選用並不一致,並非所有預設都以UTF-16LEBOM編碼為主。

關於重新導向運算子(Redirectionoperators)(>、>>)的預設編碼 從WindowsPowerShell5.1開始,預設所有>與>>導向都會委由Out-FileCmdlet處理,這也意味著預設輸出編碼是可以調整的,這部分在本文後續會提及。

但在這之前的WindowsPowerShell版本,只能輸出UTF-16LEBOM編碼。

在WindowsPowerShell5.1以前的版本,使用重新導向運算子(Redirectionoperators)預設會採用UTF-16LEBOM字集: 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode)(預設值) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 關於Get-Content(讀取內容),Add-Content(添增內容),Set-Content(取代內容)的預設編碼 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default)(預設值) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 不同Cmdlets之間,預設編碼不一樣,真的蠻讓人崩潰的。

但事實上,官網文件在針對Add-Content與Set-Content(取代內容)的說明也是有錯誤的。

當你在使用Add-ContentCmdlet的時候,他會判斷目標檔案的編碼,添加檔案時會以目標檔案的編碼為主,並不會使用Default(ANSI)編碼。

這裡所指的ANSI編碼,其實就是你控制台中地區設定的non-Unicode字集設定。

當你在使用Set-ContentCmdlet的時候,他並不會判斷目標檔案的編碼(但文件說會),所以這也是非常的雷! 當你在使用Get-ContentCmdlet的時候,預設使用Default編碼讀入。

事實上,PowerShellEngine在讀入PowerShellScript的時候,也是使用一樣的預設值。

關於Export-Csv的預設編碼 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii)(預設值) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 上表WindowsPowerShell5.1以前的版本預設值,當你在設定-Append(添加)參數的時候,他就會改先判斷目標檔案的字集,以目標檔案的字集為主。

不過Out-File也有個-Append參數,這個參數不會判斷目標檔案的字集。

(為什麼設計的這麼不一致啊?) 關於Export-PSSession的預設編碼 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8)(預設值) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 關於New-Item-TypeFile-Value的預設編碼 事實上New-ItemCmdlet並沒有-Encoding參數可用,但因為當你使用-TypeFile建立新檔案時,必須選用一個文字編碼,但他又不能指定-Encoding參數,預設值被設定成UTF8(NoBOM)編碼。

真的是非常的匪夷所思! 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌(預設值) ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 關於Send-MailMessage的預設編碼 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default)(預設值) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 關於Start-Transcript的預設編碼 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8)(預設值) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ 上表WindowsPowerShell5.1以前的版本預設值,當你在設定-Append(添加)參數的時候,他就會改先判斷目標檔案是否有BOM字元,如果有,就會以目標檔案的字集為主。

如果沒有,就會選用Ascii編碼。

變更PowerShell的預設編碼 你可以從上述的整理發現PowerShellCore6.0之後的版本,一律使用utf8NoBOM為預設編碼,一致性相當高! 但是WindowsPowerShell5.1以前的版本,預設編碼就非常混亂,很容易踩雷。

PowerShell有兩個預先定義好的變數,用來變更預設的編碼設定: $PSDefaultParameterValues 如果你想改變>或>>重新導向的預設編碼,或是使用Out-FileCmdlet時想要改變預設編碼為UTF8BOM,可以這樣設定: $PSDefaultParameterValues['Out-File:Encoding']='utf8' 如果想要改變所有Cmdlets的預設編碼,可以這樣寫: $PSDefaultParameterValues['*:Encoding']='utf8' 你可以將設定加入到$PROFILE檔案中,這樣就可以統一所有Cmdlet的預設編碼。

$OutputEncoding 這個$OutputEncoding主要用來讓PowerShellCmdlet與外部程式(externalprograms)通訊的時候,指定的文字編碼,其預設值定義如下: 字集 WindowsPowerShell5.1以前的版本 PowerShellCore6.0之後的版本 Default(ANSI) ✅(Default) ❌ OEM(作業系統預設) ✅(Oem) ✅(oem) ASCII(7-bit)字集 ✅(Ascii)(預設值) ✅(ascii) UTF7 ✅(UTF7) ✅(utf7) UTF8(NoBOM) ❌ ✅(utf8) UTF8(NoBOM) ❌ ✅(utf8NoBOM)(預設值) UTF8BOM ✅(UTF8) ✅(utf8BOM) UTF-16BEBOM ✅(BigEndianUnicode) ✅(bigendianunicode) UTF-16LEBOM ✅(String) ❌ UTF-16LEBOM ✅(Unicode) ✅(unicode) UTF-16LEBOM ❌(Unknown) ❌ UTF-32BEBOM ❌(BigEndianUTF32) ✅(bigendianutf32) UTF-32LEBOM ✅(UTF32) ✅(utf32) Bytes ❌(Byte) ❌ WindowsPowerShell5.1以前的版本,這個$OutputEncoding預設變數定義的是Ascii編碼,這意味著所有從PowerShell導向到外面的資料,預設都會轉換成這個編碼: ❯$OutputEncoding IsSingleByte:True BodyName:us-ascii EncodingName:US-ASCII HeaderName:us-ascii WebName:us-ascii WindowsCodePage:1252 IsBrowserDisplay:False IsBrowserSave:False IsMailNewsDisplay:True IsMailNewsSave:True EncoderFallback:System.Text.EncoderReplacementFallback DecoderFallback:System.Text.DecoderReplacementFallback IsReadOnly:True CodePage:20127 你可以透過[Console]::OutputEncoding取得目前Console可以使用的編碼,就會發現通常都與$OutputEncoding不一樣,這也意味著你從PowerShellCmdlet傳資料給傳統Windows外部程式的話,文字編碼通常都會出問題: ❯[Console]::OutputEncoding EncodingName:ChineseTraditional(Big5) WebName:big5 HeaderName:big5 BodyName:big5 Preamble: WindowsCodePage: IsBrowserDisplay: IsBrowserSave: IsMailNewsDisplay: IsMailNewsSave: IsSingleByte:False EncoderFallback:System.Text.InternalEncoderBestFitFallback DecoderFallback:System.Text.InternalDecoderBestFitFallback IsReadOnly:False CodePage:950 我舉的簡單的例子,在Windows有個findstr.exe工具,類似Linux下的grep工具,但是陽春很多。

假設我們在WindowsPowerShell這樣用,你會發現finstr什麼都搜尋不到,那是因為編碼不一致造成的: Get-Content.\big5-example.txt|findstr測 但是如果我們把$OutputEncoding重新宣告成[Console]::OutputEncoding,PowerShellCmdlet所有輸出就會與Console的預設輸出編碼一致: $OutputEncoding=[Console]::OutputEncoding Get-Content.\big5-example.txt|findstr測 很可惜,PowerShell並沒有$InputEncoding可用,這意味著一個重大的資訊:你不能從其他應用程式傳入non-Unicode的字元給PowerShell使用! WSL2 基本上Windows10內建所有的Terminal都是共用同一個超過30年沒有改進的核心,但是麻煩的地方在於WSL2開啟的時候,沒有chcp命令可用,而且預設Terminal採用UTF-8編碼,任何non-Unicode的編碼,通通無法正常顯示! 如下圖示,明明有4個bytes(兩個中文字),但卻一個字也吐不出來: 基本上,無解!你只能在WSL2處理Unicode編碼的文字! WindowsTerminal+WSL2 使用Microsoft最新的WindowsTerminal來執行的話,有比較好一點,可以出現四個�字元,而且你依然無法調整預設字集!😅 基本上,一樣無解!你只能在WSL2處理Unicode編碼的文字! PuTTY 使用PuTTY進行遠端連接,可以有效的解決各種編碼問題。

這是因為PuTTY內建一個叫做Charactersettranslation的功能,他可以讓你在建立連線之前,就先設定好遠端虛擬終端機想要使用預設字集,搭配著可以顯示該字集的字型,就可以正確顯示。

PuTTY預設採用UTF-8編碼,如果你的遠端Linux想以BIG5為預設字集,那麼你必須調整設定如下: 並選擇一個支援BIG5字集的字型: 連入之後,就可以正常顯示BIG5編碼的文字了 不過,當你想用WSL的時候,怎麼可能還特別安裝個OpenSSHServer然後再用PuTTY連進去,這雖然是在Linux下看到BIG5字集文字的「唯一」解決方案,但就是沒那麼漂亮! 我覺得要完美解決這個問題,大概只能依賴WindowsTerminal實現Charactersettranslation功能了,我特別到WindowsTerminal的GitHubRepo提出一個功能建議FeatureRequest:CharacterSettranslation#10870,希望日後有機會可以實現! 如何不透過PuTTY連線到Linux又能正確看到BIG5編碼的文字 我後來有研究出兩個方法,可以讓我在WSL下也能正確顯示BIG5的檔案內容: 使用cat搭配iconv轉換字集 反正文字只要能轉成UTF8就能正常顯示,所以這招可行! catbig5-example.txt|iconv-fbig5-tutf8 不過,對於含有互動的命令介面下,這招就沒效了!Orz 使用pwsh搭配$PSDefaultParameterValues['*:Encoding']='big5'設定 這個方式則是利用PowerShellCore(pwsh)的特性,將Get-Content指定編碼為big5(CodePage950),然後利用PowerShellCore預設$OutputEncoding為UTF8的特性,將文字輸出成UTF8編碼,如此以來就可以順利顯示在畫面上了!😃 pwsh-Command'Get-Content-Encodingbig5./big5-example.txt' pwsh-Command'Get-Content-Encoding950./big5-example.txt' 我可以寫成一個Alias專門來做這件事: aliascatb5='pwsh-Command'"'"'Get-Content-Encodingbig5'"'"'' catb5./big5-example.txt 請注意:不要在PowerShellCoreonLinux使用cat命令,因為他會執行/usr/bin/cat命令,而非Get-ContentCmdlet喔! 總結 反正遇到編碼問題就是有著數不盡的地雷要踩,還好這幾年累積了無數踩雷經驗,今天終於將我所知道的編碼問題全部整理起來,心中頓時覺得踏實許多!😄 本文有點長,我特別節錄幾個重點知識: Windows命令提示字元(CommandPrompt)可以用chcp切換預設編碼 chcp65001 PowerShell5.1+可以透過修改$PSDefaultParameterValues['*:Encoding']改變重新導向運算子的預設編碼 $PSDefaultParameterValues['*:Encoding']='utf8' Get-Content./big5-example.txt PowerShell5.1+預設所有>與>>導向都會委由Out-FileCmdlet處理 $PSDefaultParameterValues['Out-File:Encoding']='utf8bom' Get-Content./big5-example.txt>abc.txt PowerShell5.1+可以透過修改$OutputEncoding改變Pipe給外部程式的預設編碼 $OutputEncoding=[Console]::OutputEncoding Get-Content./big5-example.txt|findstr/i測 PowerShellCore的編碼可以透過[System.Text.Encoding]::GetEncodings()取得完整清單,設定-Encoding的時候,可以指定CodePage的數字,也可以指定編碼名稱 [System.Text.Encoding]::GetEncodings() Get-Content-Encoding950./big5-example.txt Get-Content-Encoding'big5'./big5-example.txt PuTTY內建一個叫做Charactersettranslation的功能,他可以讓你在建立連線之前,就先設定好遠端虛擬終端機想要使用預設字集,搭配著可以顯示該字集的字型,就可以正確顯示。

相關連結 [Console]::OutputEncodingunableswitchtocp950encodinginLinux#15865 $OutputEncodingtotherescue|PowerShellTeam UnderstandingdefaultencodingandChangethesameinPowerShell PowerShell輸出結果編碼問題 Howtoreadpipelinewithiso-8859-1encodingcharacters?#15871 HowtochangedefaultcodepageinWindowsTerminalusingWSL?-SuperUser Putty中文顯示@廖董不懂的部落格::痞客邦:: 相關文章 WindowsPhone7.5(Mango)開發學習資源整理 芒果終於要來了,昨天已經正式釋出WindowsPhoneSDK7.1RTM繁體中文版,而估計在幾週內應該所有WindowsPhone7的使用者就能夠自動更新到支援多國語系、完整的中... WindowsContainer版本相容性與多重架構容器映像介紹 自從Windows核心版本v14393開始,也就是WindowsServer2016LTSC與Windows10年度更新版,正式開始支援Windows容器,這意謂著企業可以 徹底釐清Windows10與WindowsServer的版本編號 這些年一直對Windows10與WindowsServer的版本編號困擾著,經常會聽到什麼Windows10周年更新、Windows10創作者更新之類的名稱,完全摸不著頭緒,你 工商服務(廣告) 每月文章 2022 十月(5) 九月(17) 八月(10) 七月(11) 六月(4) 五月(10) 四月(5) 三月(9) 二月(9) 一月(15) 2021 十二月(12) 十一月(5) 十月(6) 九月(13) 八月(16) 七月(13) 六月(13) 五月(7) 三月(1) 二月(1) 2020 十二月(3) 十一月(1) 十月(3) 九月(7) 八月(7) 七月(9) 六月(2) 五月(5) 三月(4) 二月(5) 一月(4) 2019 十二月(7) 十一月(2) 十月(5) 九月(1) 六月(3) 四月(4) 三月(3) 二月(7) 一月(12) 2018 十二月(3) 十一月(1) 十月(4) 九月(12) 八月(4) 六月(2) 五月(3) 四月(6) 二月(1) 一月(2) 2017 十二月(2) 十月(3) 九月(4) 七月(1) 六月(1) 五月(1) 四月(1) 二月(3) 一月(4) 2016 十二月(4) 十一月(1) 十月(1) 九月(4) 八月(3) 七月(2) 五月(1) 四月(1) 三月(3) 二月(3) 一月(2) 2015 十二月(6) 十一月(4) 十月(3) 九月(5) 八月(1) 七月(4) 六月(2) 五月(3) 四月(1) 三月(1) 二月(3) 一月(2) 2014 十二月(3) 十一月(2) 十月(3) 九月(3) 八月(1) 七月(4) 六月(2) 五月(4) 四月(5) 三月(4) 二月(1) 一月(7) 2013 十二月(1) 十一月(8) 十月(1) 九月(2) 八月(4) 七月(5) 六月(8) 五月(9) 四月(8) 三月(10) 二月(9) 一月(10) 2012 十二月(4) 十一月(6) 十月(6) 九月(4) 八月(5) 七月(10) 六月(5) 五月(6) 四月(10) 三月(12) 二月(1) 一月(6) 2011 十二月(3) 十一月(7) 十月(8) 九月(14) 八月(15) 七月(10) 六月(10) 五月(11) 四月(11) 三月(13) 二月(14) 一月(13) 2010 十二月(13) 十一月(10) 十月(16) 九月(17) 八月(12) 七月(22) 六月(15) 五月(11) 四月(14) 三月(17) 二月(17) 一月(26) 2009 十二月(16) 十一月(18) 十月(18) 九月(23) 八月(20) 七月(26) 六月(24) 五月(21) 四月(26) 三月(30) 二月(27) 一月(26) 2008 十二月(30) 十一月(31) 十月(31) 九月(29) 八月(31) 七月(31) 六月(30) 五月(30) 四月(31) 三月(31) 二月(29) 一月(33) 2007 十二月(31) 十一月(37) 十月(13) 文章分類 .Net (223) .NETCore (57) Accessibility (3) Angular (25) AngularJS (11) ASP.NET (223) ASP.NET5 (3) ASP.NETBlazor (1) ASP.NETCore (37) ASP.NETIdentity (2) ASP.NETMVC (105) ASP.NETWebAPI (13) AzureDevOps (33) C# (127) CloudComputing (4) CSS (29) DevOps (22) Docker (28) EntityFramework (23) Git (31) Golang (2) HTML5 (8) IIS (103) Java (26) JavaScript (108) Jenkins (7) Kubernetes (15) LINQ (36) Linux (114) MicroK8s (7) MicrosoftAzure (41) MySQL (15) Office (49) Office365 (28) Oracle (10) PHP (25) Scrum (1) Security (66) SQLServer (127) Subversion (35) SystemCenter (2) TFS (6) TFS2010 (10) Tips (190) UnitTesting (10) Usability (1) VBA (5) VisualBasic (5) VisualStudio (122) VisualStudio11 (2) VisualStudio2012 (10) VisualStudio2013 (4) VS2010Tips (23) Web (172) WebMatrix (8) Windows (45) Windows8 (14) WindowsAzure (18) WindowsPhone7 (14) 介紹好用工具 (228) 心得分享 (88) 多奇快訊 (9) 系統管理 (368) 前端工程研究 (20) 專案管理 (8) 團隊合作 (9) 網路管理 (22)



請為這篇文章評分?