进一步阅读

进一步阅读

当您在 Linux 上运行 cal 时,当月的输出将反转视频突出显示当天。当我将该输出发送到 hexdump -c 时,我得到了一些有趣的结果:

0000000               N   o   v   e   m   b   e   r       2   0   1   6
0000010                          \n   S   u       M   o       T   u    
0000020   W   e       T   h       F   r       S   a          \n        
0000030                       1           2       _  \b       _  \b   3
0000040           4           5          \n       6           7        
0000050   8           9       1   0       1   1       1   2          \n
0000060   1   3       1   4       1   5       1   6       1   7       1
0000070   8       1   9          \n   2   0       2   1       2   2    
0000080   2   3       2   4       2   5       2   6          \n   2   7
0000090       2   8       2   9       3   0                            
00000a0                  \n                                            
00000b0                                              \n                
00000bc

正如您所看到的,在今天突出显示的“3”之前打印了一个不可见的序列 _\b _\b。 _ 是下划线(ASCII 十六进制中的 5F),\b 是 Ctrl-H 或 ASCII 十六进制中的 08。这是什么?我知道有很多晦涩的终端代码,但我希望它使用更标准的东西,比如 \e[7m.更奇怪的是,我无法通过使用标准 printf 函数(如以下命令之一)打印出相同的字符来重现 cal 的相同行为:

/usr/bin/printf "1 2 _\b _\b3 4 5\n"
/usr/bin/printf "1 2 _^H _^H3 4 5\n"

其中 ^H 是通过按 Ctrl-V Ctrl-H 生成的。但它们都不能产生与 cal 相同的逆视频输出。我什至尝试编写一个小 C 程序来做到这一点。我也尝试过使用 echo -e 。有趣的是,虽然它不会反转终端中的视频,但如果我通过 less -R 传输输出,它会将其颜色更改为黄色并为其添加下划线。在其他终端上我尝试过它只是强调它。这看起来几乎有点过分,但如果我使用 _ 以外的字符,它就不起作用,这让我认为 _\b 是单个代码序列。那么该角色的视频如何反转呢?

对此有何见解?

手册页说 cal 的输出应该是与原始 Unix cal 命令有点兼容的版本。所以我只能假设这是一些古老的代码。

答案1

这几乎看起来有点过分了

正是如此。正如所讨论的为什么 80 列的控制台上有 11 个制表符?,当谈到 Unix 终端时,它有助于思考机械打字机的操作。在这种情况下,字符之前的序列_ BS(退格字符)是一种约定,用于指示该字符的下划线,因为在某些终端上,这就是文本下划线的方式。另一种控制序列是_字符后的 BS。当然,在最初的终端上,什么超出什么并不重要。在现代视频终端上,最后写入的字符“获胜”,从而擦除之前的数据。因此,_ BS <字符>顺序优先。

FreeBSD ncal,也就是这个程序,在突出显示方面有两种操作模式。

  • 如果其输出是终端,它会在 termcap 数据库中查找当前终端类型的sose序列,并在突出显示的文本的两侧发出这些序列。 (实际上,执行此操作的代码中有一个错误,与堆栈上的缓冲区超出范围及其内容稍后使用有关,似乎没有人发现这一点。)
  • 如果它的输出不是终端,它会发出文本,其中每个要突出显示的字符前面都有_BS 序列。

你不能通过向终端发出 BS 序列来复制这一点_,除非(当然)你的终端是这样强调内容的终端之一。终端模拟器不是这种情况,而且几乎可以肯定,您在这里使用的任何终端或终端模拟器都不是这种情况。

但是,您可以筛选通过程序使用此约定的文本,ul该程序识别此约定以及其他几个类似打字机的约定,并将它们转换为终端实际的控制序列,并在 termcap 数据库中查找它们。您也可以printf通过过滤命令的输出ul

在其他终端上我尝试过它只是强调它。

ncal具有讽刺意味的是,通过程序过滤非终端模式输出ul实际上比让ncal编写终端控制序列本身稍好一些。而ncal使用终端的脱颖而出模式,ul将尝试使用终端的实际强调转换 BS 序列时的模式(如果有)_。正如 termcap 手册所解释的,突出模式可以是任何适合终端的模式(包括粗体、反向视频或颜色),并且不一定是下划线。在您的一个终端上,它显然是下划线和颜色变化的组合。

此外,ul还可以处理没有下划线开始/结束序列但有下划线最后一个字符序列的终端。具有讽刺意味的是,ul如果您的终端能够应对真的是_一个在每个字符后面加上 BS 来强调的,而ncal无法应对。

当然,ul没有ncal缓冲区处理错误。 ☺

如果我将输出通过管道传输到less -R,它会将其颜色更改为黄色并为其添加下划线。

正如您所发现的,该less程序理解_BS 序列并按照ul程序的方式处理它们。并不完全一样。 ul可以处理涉及多个 BS 字符的序列_,也可以处理类似的粗体字符序列。 less不能。对比一下您从这两者中看到的情况:

  • /usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4。\b\b\b45 6\n" |乌尔
  • /usr/bin/printf "1 2 ______\b\b\b\b\b\b 3 _\b4。\b\b\b45 6\n" |较少的

回到过去的美好时光

可悲的是,这些仍然是“美好的旧时光”。不要让人们欺骗您,让您相信现在很少使用此功能。

它不在手册中,但源代码指出ul它正在尝试实现 Teletype Model 37 的控制序列处理,因为“这就是输出nroff”。原始 Unix 程序的 GNU 替代品nroff是在终端获得颜色、粗体和斜体等奇特功能很久之后编写的,能够生成ECMA-48颜色、粗体和斜体的控制序列。事实上确实如此在正常情况下

nroff及其 GNU 替代品用于格式化手册页以在终端上显示。可悲且讽刺的是,从它编写大约 10 年后开始,人们开始对 GNU 工具进行阻碍,以便它生成 1968 年的旧 Teletype Model 37 序列,而不是 1976 年的“新”ECMA-48 控制序列(原文如此!)。他们使用修改其默认行为的选项进行man调用groff,并添加强制额外 ditroff 输出的未记录文件。

每次您在终端上阅读手册页时,手册系统都会运行groff,该系统会尽职尽责地将手册源文本转换为使用这些旧的 Teletype Model 37 控制序列的输出字符流,这些控制序列lessmore正在转换为终端的控制序列。

进一步阅读

  • 乔纳森·德博因·波拉德 (2016)。  nosh 用户空间虚拟终端上手册页中的斜体和颜色存档版本,当前版本)。小吃包。
  • 乔纳森·德博因·波拉德 (2017)。  改进的手册页ul存档版本,当前版本)。提案。

答案2

Ctrl-H是退格键,它将光标向左移动一步。在过去的好日子里,发送下划线、退格键和其他一些字符是在硬拷贝(“纸质”)终端上给某些内容加下划线的方法。这用于在 的输出中突出显示当天cal

我的cal程序在运行时konsole不会输出此序列。如果我运行script -c cal并检查生成的typescript文件,我可以看到 cal 程序使用转义序列<esc>[7m切换到反转模式视频。

相关内容