Ell*_*t B 17 terminal-emulator character-encoding centos macos
我正在运行 CentOS 7.9,今天我的终端显示奇怪的字符。有些字母看起来不错,但有些符号显示为一些非英文字符。例如,我制作了一个包含以下内容的文本文件:
!@#$%^&*()_+{}
Run Code Online (Sandbox Code Playgroud)
当我打开这个vi
或者nano
它看起来正如我上面写的是正确的。但在终端中它看起来像这样:
$ cat chars.txt
!É#$%Ü&*()_+äå
$ od -An -vtx1 < chars.txt
21 40 23 24 25 5e 26 2a 28 29 5f 2b 7b 7d 0a
Run Code Online (Sandbox Code Playgroud)
这些奇怪的字符随处可见,即使在我打字时也是如此。这台机器一直工作到今天。我认为这是在我下载了一个二进制文件curl
并忘记使用该-O
参数之后发生的。重新启动并以其他用户身份登录没有帮助。我的语言环境设置如下;我不知道还有什么要找的。我使用的 shell 是 Bash 4.2 版,没什么异常。
$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
Run Code Online (Sandbox Code Playgroud)
编辑:说服务器的外壳是 bash 4.2 会更准确。我在 macOS Big Sur 上使用 Terminal.app 登录。
Sté*_*las 60
xterm
如果我这样做,我可以使用终端模拟器(版本 366)重现它:
$ printf '\e[?42h\e(H'; cat chars.txt; printf '\e(B\e[?42l'
!É#$%Ü&*()_+äå
Run Code Online (Sandbox Code Playgroud)
在哪里:
其他人撤消设置。
要将终端恢复到正常状态,您还可以使用 ncursesreset
命令。在这里,我发现\ec
它发送的序列(例如发送的rs1
/reset_1string
能力tput rs1
)负责恢复默认字符集)。
至于为什么nano
例如正常显示它们,您会发现,如果您nano
在script
命令会话中运行并typescript
随后查看结果,nano
则\e(B
在切换到备用屏幕后\e[?1049h
可能会发送一个序列(为 G0 选择 US-ASCII)作为某些 ncurses 初始化的一部分,并且nano
在退出时离开该备用屏幕时会恢复原始字符集。
现在,\e(H
在一个二进制文件中偶然获得一个序列(0x1b 0x28 0x48 字节序列)是合理的。平均而言,1600 万个随机 3 字节序列中就有一个是那个序列。在这里,我找到了一些:
$ LC_ALL=C grep -rFl $'\e(H' /lib
/lib/x86_64-linux-gnu/libicui18n.so.66.1
/lib/x86_64-linux-gnu/ceph/libceph-common.so.2
[...]
Run Code Online (Sandbox Code Playgroud)
例如。
但是\e[?42h
偶然发现6 字节(48 位)序列的可能性要小得多(280 万亿个 6 字节序列中的 1 个)。更重要的是,\e(H
在您转储到终端上的随机二进制文件中同时具有该顺序和顺序。
但是xterm
在 CentOS7 上是旧版本(295)。在那个版本中,\e[?42h
不需要启用 ISO2022 处理的序列。在该版本中xterm
,\e(H
仅凭 就足以获得该行为。这在2013 年 9 月发布的297 版本中发生了变化。这解释了为什么在 CentOS7 或那个时代的任何系统中比在最近的系统中更可能遇到这种情况。
正如你指出你的工作站正在运行MacOS和不CentOS的,需要注意的是MacOS的似乎与更老版本的现身xterm
(269
如2021年),和我期望Terminal.app
你明确你实际使用的终端仿真器具有相同的错误是xterm
使用拥有(因为它没有正确模拟 VT220 终端,尽管它的目的可能是模拟那些旧版本xterm
)。
在更老的天(直到xterm的182即转变我相信)倾销二进制文件到终端的时候,另一种常见的人工制品被切换到特殊字符和线条设置时为0x0E字节(SO
/^N
控制字符)被送往终端。SO
仍然切换到 G1 集,但当时 G1 集被初始化为线图集。通过发送\e(0
选择G0的线图集的序列,您今天可以获得相同的效果(尽管它不太可能发生在随机二进制文件中):
$ printf '\e(0 blahblah \e(B\n'
????????
Run Code Online (Sandbox Code Playgroud)
您可以回到旧的行为,其中^N
/^O
在 ASCII 和带有序列的线条图集之间切换\e)0
。
至于为什么重新启动没有帮助,请记住,是您的终端模拟器受到该转义序列的影响。重新启动您ssh
从该终端模拟器进入的系统无济于事。重新启动您运行的系统xterm
会有所帮助,但仅重新启动该终端仿真器或reset
在终端内运行如上所示的该命令(本地或通过ssh
,只要将rs1
转义序列发送到就无关紧要)终端模拟器)。
更多信息请访问:
xterm
) 归档时间: |
|
查看次数: |
1692 次 |
最近记录: |