GNU 屏幕:使用 -d -m 时出现奇怪的 TERMCAP

GNU 屏幕:使用 -d -m 时出现奇怪的 TERMCAP

根据我的运行方式screen,它要么有或没有正确的 TERMCAP 信息。其症状是颜色并不总是正确显示在我的终端中(例如:ls、vim 语法突出显示等)。

这工作正常:

$ echo $TERMCAP
  <empty output>
$ screen -S foo
$ screen -r foo
  <now I'm inside a screen session>
$ echo $TERMCAP
  <long output>
$ ls
  <nice pretty colors>

这有问题:

$ echo $TERMCAP
  <empty output>
$ screen -d -m -S foo
$ screen -r foo
  <now I'm inside a screen session>
$ echo $TERMCAP
  <long output, but different than before>
$ ls
  <no colors ):>

现在,我可以解决这个问题。我可以手动修改我的 TERMCAP 等。

但我真的很想了解发生了什么事。如果可能的话,我想找到一个“干净”的解决方案。

有人知道这是怎么回事吗?如果我-d -m在跑步时使用它会有什么区别screen

如果这很重要的话,这是在 FreeBSD 上的。

答案1

当您使用这些-d -m选项时,screen开始于超然的模式,在这种情况下,不会尝试根据当前TERM变量改进其终端描述。它仅TERM在正常启动(未分离)时查找您的变量。当您附加到以分离方式启动的会话时,基于 进行此初始化为时已晚TERM

这部分16.1 选择窗口的 termcap 条目手册中描述了它所做的一些修复。

您所看到的非工作案例如下所示:

TERMCAP=SC|屏幕|VT 100/ANSI X3.64 虚拟终端:\
        :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:\
        :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:ct=\E[3g:\
        :do=^J:nd=\E[C:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\EM:\
        :le=^H:bl=^G:cr=^M:it#8:ho=\E[H:nw=\EE:ta=^I:is=\E)0:\
        :li#24:co#80:am:xn:xv:LP:sr=\EM:al=\E[L:AL=\E[%dL:\
        :cs=\E[%i%d;%dr:dl=\E[M:DL=\E[%dM:dc=\E[P:DC=\E[%dP:\
        :im=\E[4h:ei=\E[4l:mi:IC=\E[%d@:ks=\E[?1h\E=:\
        :ke=\E[?1l\E>:vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\
        :ti=\E[?1049h:te=\E[?1049l:k0=\E[10~:k1=\EOP:k2=\EOQ:\
        :k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:k7=\E[18~:\
        :k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\
        :kh=\E[1~:@1=\E[1~:kH=\E[4~:@7=\E[4~:kN=\E[6~:kP=\E[5~ :\
        :kI=\E[2~:kD=\E[3~:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:

而好的看起来像这样:

TERMCAP=SC|屏幕|VT 100/ANSI X3.64 虚拟终端:\
        :DO=\E[%dB:LE=\E[%dD:RI=\E[%dC:UP=\E[%dA:bs:bt=\E[Z:\
        :cd=\E[J:ce=\E[K:cl=\E[H\E[J:cm=\E[%i%d;%dH:ct=\E[3g:\
        :do=^J:nd=\E[C:pt:rc=\E8:rs=\Ec:sc=\E7:st=\EH:up=\EM:\
        :le=^H:bl=^G:cr=^M:it#8:ho=\E[H:nw=\EE:ta=^I:is=\E)0:\
        :li#25:co#80:am:xn:xv:LP:sr=\EM:al=\E[L:AL=\E[%dL:\
        :cs=\E[%i%d;%dr:dl=\E[M:DL=\E[%dM:dc=\E[P:DC=\E[%dP:\
        :im=\E[4h:ei=\E[4l:mi:IC=\E[%d@:ks=\E[?1h\E=:\
        :ke=\E[?1l\E>:vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\
        :ti=\E[?1049h:te=\E[?1049l:us=\E[4m:ue=\E[24m:so=\E[3m:\
        :se=\E[23m:md=\E[1m:mr=\E[7m:me=\E[m:ms:\
        :Co#8:pa#64:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:AX:G0:\
        :as=\E(0:ae=\E(B:\
        :ac=\140\140aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:\
        :k0=\E[10~:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:\
        :k6=\E[17~:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:\
        :F1=\E[23~:F2=\E[24~:kb=^H:K2=\EOE:kB=\E[Z:kh=\E[1~:\
        :@1=\E[1~:kH=\E[4~:@7=\E[4~:kN=\E[6~:kP=\E[5~:kI=\E[2~ :\
        :kD=\E[3~:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:km:

在好的情况下,screen注意到它TERM被设置为xterm,并从该描述中添加了功能。

在 FreeBSD 中您会注意到这个问题,因为当您将描述限制为 termcap 应用程序假定的 1023 字节限制时,分发的 termcapscreen没有颜色(额外的设置将被丢弃)。在其他平台上,您可能会使用描述由 ncurses 提供,其中告诉如何使用颜色。差异不是由于所使用的库造成的;而是由于所使用的库造成的。虽然screen是一个术语应用程序,它在 FreeBSD 上使用 ncurses:

$ ldd `which screen`
/usr/local/bin/screen:
    libncurses.so.8 => /lib/libncurses.so.8 (0x80086a000)
    libelf.so.1 => /usr/lib/libelf.so.1 (0x800ab6000)
    libutil.so.9 => /lib/libutil.so.9 (0x800ccb000)
    libulog.so.0 => /lib/libulog.so.0 (0x800edd000)
    libcrypt.so.5 => /lib/libcrypt.so.5 (0x8010df000)
    libc.so.7 => /lib/libc.so.7 (0x8012ff000)
    libmd.so.6 => /lib/libmd.so.6 (0x801698000)

相反,差异是由于

  • FreeBSD 优先使用 termcap 数据库构建 ncurses,而不是 terminfo(您可以使用端口获取 terminfo 数据库),并且
  • FreeBSD 有一个 termcap 文件,它与其他终端数据库不匹配。虽然已经进行了一些修复,但它仍然存在一些怪癖,例如VT100s 彩色, 和修改使其控制台与真正的 xterm 之间的差异TERM=xterm不那么明显(当然,使用 xterm 的人除外)。

有点讽刺的是,人们可能会注意到screen设置TERMCAP为多行格式。它在 4.2BSD 和 4.3BSD 中使用,但在 4.4BSD 中已过时(大约 25 年前),改用散列数据库并同时丢弃空格(这与 termcap 大小的 1023 字节限制相比较) 。自从 FreeBSD在 20 世纪 90 年代改用 ncurses,该格式已经过时,很少有应用程序依赖该TERMCAP变量。但ls就是其中之一。

screen确实有一个-T选项应该通过指定特定的 termcap 条目(有颜色)来帮助解决此问题,但在测试它时,似乎无法解决问题。

进一步阅读:

答案2

好吧,我得到了一些没有的东西解决这个问题的毛病:

在我创建screen会话的脚本中,靠近顶部有:

# This runs the commands:
# TERM=screen
# TERMCAP='...'
# with values appropriate for a 'screen' terminal
eval "$(tset - -s screen | tail -n+2)"

# Set up the SCREENCAP variable, which 'screen' will use for new sessions
SCREENCAP="$TERMCAP"; export SCREENCAP

# ...

screen -d -m -S my-session

现在,当我连接到 时my-session,终端颜色可以工作。

不完全令人满意,但效果足够好。

相关内容