我使用的是 Windows 11 和“新版 Windows 终端”(Windows 11 中用于控制台的默认和“主要”应用程序,既不是旧的cmd.exe
也不是新的PowerShell.exe
)。它开箱即用地支持 UTF-8,并且可以显示非拉丁字符、emodji 等(如果它们出现在 UTF-8 代码页中)。
在该终端中,我运行默认的 Ubuntu wsl 配置文件。从该 wsl Ubuntu 命令行,我ssh
访问远程非 Windows 服务器。
如果服务器使用 UTF-8 代码页,一切看起来都很好。但如果服务器使用“经典”非 UTF 代码页,我就无法在终端中看到非拉丁字符。附图左侧部分显示了问题。
例如,我有一个旧的 FreeBSD 服务器,它不支持开箱即用的控制台 UTF-8(并且没有理由实现它 - 这种服务器是一种已经运行了几十年的传统服务器)。
如果我使用putty
ssh 连接该服务器 - 我只需在窗口 -> 翻译 -> 字符集 -> 远程字符集菜单中设置正确的代码页(通常KOI8-R
或Win1251 (Cyrillic)
对于设置为使用西里尔语的服务器来说是正确的选择)。
如何在“新 Windows 终端”中设置相同的行为?它有几十种设置,但我找不到有关代码页的任何信息。
或者也许我应该ssh
在 Windows 端使用一些特殊(非终端)设置来动态转换远程服务器输出?
答案1
使用luit
(或可能screen
)作为代码页转换的中间层。
作为参考,“旧 Windows 终端”通常称为“Windows 控制台”,后来称为“Conhost”。它不是 Cmd/PowerShell 的一部分。
例如,我有一台旧的 FreeBSD 服务器,它不支持开箱即用的控制台中的 UTF-8
不需要——SSH 不以任何方式涉及远程系统的控制台(输出不通过 syscons);它所需要的只是程序输出UTF-8 编码数据。例如,2008 年安装的 FreeBSD 已经具备 UTF-8 编码能力。
如何在“新 Windows 终端”中设置相同的行为?它有几十种设置,但我找不到有关代码页的任何信息。
Windows Terminal 似乎没有这样的设置,它依赖于底层控制台系统来执行转换(它仍然与 Conhost 共享此代码的核心)。打开常规的 PowerShell 或 Cmd 选项卡,然后测试如果在从同一chcp 878
选项卡进入 WSL 之前运行会发生什么。
Windows 控制台中的代码页通常有点奇怪,因为底层系统基于 UTF-16,但有两个 API,一个用于写入“OEM 代码页”文本,另一个用于写入 UTF-16 文本。传统上,“OEM 代码页”设置为 437 或 775(大致相当于系统设置为的“ANSI”代码页的 MS-DOS 等效值),尽管 Windows Terminal 现在将其设置为 65001,表示它需要 UTF-8。理论上,如果您这样做chcp 878
,这将使控制台与 KOI8-R 一起工作。
因此,由于 Conhost 长期以来要么使用 UTF-16 要么使用 OEM 代码页,因此 Win32-OpenSSH 中实际上还有另一个转换层 - ssh.exe
Windows 附带的版本总是在运行时将控制台代码页设置为 65001,并假定 SSH 服务器的输出为 UTF-8。这不会影响ssh
您在 WSL 中的 Linux 命令……但我强烈怀疑wsl.exe
您用于进入整个 Ubuntu 环境的命令可能会执行相同的操作 - 它可能始终强制将控制台强制为 UTF-8,甚至转换为 UTF-16。