为什么“cal”使用奇怪的 08 / ^H / \b 终端代码来突出显示以及它是如何工作的?

del*_*ray 5 highlighting escape-characters cal ansi-term

当您在 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
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在今天突出显示的“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"
Run Code Online (Sandbox Code Playgroud)

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

对此有何见解?

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

Joh*_*éen 3

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

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