检测我的终端支持多少 Unicode,甚至通过屏幕

检测我的终端支持多少 Unicode,甚至通过屏幕

问题是:我希望能够辨别我的终端是否能够使用像样的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

相关内容