问题是:我希望能够辨别我的终端是否能够使用像样的unicode,以便使用某些字符,就像扫视一样,有时使用颜色和其他下划线。
动机的出现是因为在任何类型的虚拟终端中我都能得到不错的字体,但我知道基本的 Linux 控制台具有 256 或 512 个同时符号的字符集,因此你不能指望完整的字体支持。
起初我以为我可以使用$TERM
或 tty,但问题是:我也在使用 byobu,所以$TERM
总是“screen.linux”。 tty 的输出也不是很能说明/dev/pts/<some number>
问题:无论是“真实”还是虚拟。
$BYOBU_TTY
也没有帮助,因为例如它可能是,并且当在+ +/dev/tty1
中打开会话时,字符不会显示,但是当从某个 X 术语附加到同一会话时,它们会正确显示并且仍然不会改变。此外,我希望能够检测到这一点,而无需假设 byobu 是否存在。CtrlAltF1$BYOBU_TTY
此外,区域设置在所有情况下都显示 en_US.UTF-8
然而不知何故,即使在 byobu 内部,也会根据我附加到 byobu 会话的终端使用不同的输出(命名一个我看到检测到这一点的特定工具)。
我在使用谷歌时遇到了麻烦,因为终端和 tty 似乎太常见的搜索词。我最多得出推荐$TERM
或 tty 的解决方案。
答案1
好吧,首先我想我会指出,从你所说的意义上来说,现在几乎所有终端都是“虚拟的”......即使终端位于真正的串行端口的另一端。我的意思是,那些日子VT-100s,慧思终端和其他“物理”、“真实”终端几乎消失了!
除此之外,假设您想要检测您的终端支持哪种 Unicode。您可以通过向 is 写入测试字符并查看会发生什么来完成此操作。 (您可以在写入后尝试擦除测试字符,但用户可能仍然会短暂地看到它们,或者擦除它们可能一开始就无法正常工作。)
这个想法是要求终端告诉你它的光标位置,输出一个测试字符,再次要求终端告诉你它的位置,然后比较两个位置以查看终端的光标移动了多远。
要询问终端的位置,请参阅这里。本质上:
echo -e "\033[6n"; read -d R foo; echo -en "\nCurrent position: "; echo $foo | cut -d \[ -f 2
尝试输出“é”。该字符在 UTF-8 中占用 2 个字节,但仅显示在屏幕上的一列中。如果您检测到输出“é”导致光标移动 2 个位置,则终端根本不支持 UTF-8,并且可能输出了某种垃圾。如果光标根本没有移动,那么终端可能只是 ASCII。如果移动了 1 个位置,那么恭喜你,它大概可以显示法语单词了。
尝试输出“あ”。该字符在 UTF-8 中占用 3 个字节,但在屏幕上仅显示为两列。如果光标移动了 0 或 3,则有坏消息,与上面类似。如果它移动 1,那么看起来终端支持 UTF-8 但不知道宽字符(固定宽度字体)。如果它移动了 2 列,那么一切都很好。
我确信您可以发出其他探测字符,这将带来有用的信息。我不知道有什么工具可以自动执行此操作。
答案2
OP 的实际问题是:Linux 控制台支持哪些 Unicode 值,以及在运行screen
.原则上,可以通过检索控制台的 Unicode 映射来完成此操作。
源代码kbd
树包含getunimap
(及其手册页)。手册页说
getunimap 程序是旧的并且过时的。它现在是 setfont 的一部分
这并不完全正确。 setfont
有一个选项可以大致一样的东西:
-ou file
Save previous Unicode map in file
差异:
setfont
写入文件,同时getunimap
写入标准输出getunimap
显示将被映射的字符,作为注释。
例如:
0x0c4 U+2500 # ─
0x0c4 U+2501 # ━
0x0b3 U+2502 # │
0x0b3 U+2503 # ┃
0x0da U+250c # ┌
0x0da U+250d # ┍
0x0da U+250e # ┎
0x0da U+250f # ┏
0x0bf U+2510 # ┐
0x0bf U+2511 # ┑
0x0bf U+2512 # ┒
0x0bf U+2513 # ┓
0x0c0 U+2514 # └
0x0c0 U+2515 # ┕
0x0c0 U+2516 # ┖
0x0c0 U+2517 # ┗
相对
0xc4 U+2500
0xc4 U+2501
0xb3 U+2502
0xb3 U+2503
0xda U+250c
0xda U+250d
0xda U+250e
0xda U+250f
0xbf U+2510
0xbf U+2511
0xbf U+2512
0xbf U+2513
0xc0 U+2514
0xc0 U+2515
0xc0 U+2516
0xc0 U+2517
如果您正在运行screen
(或者例如正在运行xterm
并且不是在控制台上),您将收到权限错误,您可以使用 解决该错误sudo
。
如果我碰巧知道加载了哪种字体,我可以使用以下命令进行检查(无需特殊权限)psfgettable
,例如,
zcat /usr/share/consolefonts/Lat2-Fixed16.psf.gz | psfgettable -
并查看用于加载字体的映射数据setfont
(使用 Unicode 映射):
#
# Character table extracted from font -
#
0x000 U+00a9
0x001 U+00ae
0x002 U+00dd
0x003 U+0104
0x004 U+2666 U+25c8 U+fffd
0x005 U+0105
0x006 U+0111
0x007 U+0150
0x008 U+0151
0x009 U+0162
0x00a U+0164
0x00b U+0170
0x00c U+0171
0x00d U+021a
0x00e U+02dd
0x00f U+2014 U+2015
0x010 U+2020
0x011 U+2021
0x012 U+2022 U+25cf
...
getunimap
和都setfont
给出未排序的数据,而psfgettable
看似已排序(以及组合映射到相同字形的 Unicode 值的行)。因此存在差异,但信息是可访问的。
进一步阅读(说明为什么你不能用它showconsolefont
来解决这个问题):
答案3
我遇到这个问题是因为我试图完成同样的事情,但不想在屏幕上留下任何内容并让它设置一个变量,所以我将以下内容放入我来源的 shell 脚本中:
function test_unicode {
echo -ne "\xe2\x88\xb4\033[6n\033[1K\r"
read -d R foo
echo -ne "\033[1K\r"
echo -e "${foo}" | cut -d \[ -f 2 | cut -d";" -f 2 | (
read UNICODE
[ $UNICODE -eq 2 ] && return 0
[ $UNICODE -ne 2 ] && return 1
)
}
test_unicode
RC=$?
export UNICODE_SUPPORT=`[ $RC -eq 0 ] && echo "Y" || echo "N"`
unset test_unicode