GNU Screen – Fix Strange TERMCAP When Using -d -m

gnu-screentermcap

Depending on how I run screen, it either does or does not have the right TERMCAP info.
The symptom of this is that colors don't always show up in my terminal correctly (eg: ls, vim syntax highlighting, etc).

This works fine:

$ 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>

This has problems:

$ 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 ):>

Now, I can work around this. I can fiddle with my TERMCAP manually, etc.

But I'd really like to understand what's going on.
I'd like to find a 'clean' solution, if possible.

Does anybody know what's going on here?
What difference should it make if I use -d -m when running screen?

This is on FreeBSD, if that matters.

Best Answer

When you use the -d -m options, screen starts in detached mode, and in that case does not attempt to improve its terminal description based on your current TERM variable. It only looks for your TERM variable when it is started normally (not detached). When you attach to the session which was started detached, it is too late to do this initialization based on TERM.

The section 16.1 Choosing the termcap entry for a window in the manual describes some of the fixes it does.

What you saw for the non-working case looks like this:

TERMCAP=SC|screen|VT 100/ANSI X3.64 virtual terminal:\
        :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:

while the good one looks like this:

TERMCAP=SC|screen|VT 100/ANSI X3.64 virtual terminal:\
        :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:

In the good case, screen noticed that TERM was set to xterm, and added capabilities from that description.

You will notice this problem with FreeBSD because the termcap distributed with screen does not have color, when you limit the description to the 1023-byte limit assumed by termcap applications (the extra settings are discarded). On other platforms, you likely would be using the description provided by ncurses, which does tell how to use color. The difference is not due to the library used; although screen is a termcap application, it uses ncurses on FreeBSD:

$ 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)

Instead, the difference is due to

  • FreeBSD builds ncurses using the termcap database in preference to terminfo (you can get the terminfo database using a port), and
  • FreeBSD has a termcap file, which does not match other terminal databases. While some fixes have been made, it still has quirks such as VT100s with color, and modifications to make the differences between its console with TERM=xterm and a real xterm less apparent (except to people using xterm, of course).

Somewhat ironically, one may notice that screen sets TERMCAP to a multi-line format. That was used in 4.2BSD and 4.3BSD, but made obsolete in 4.4BSD (around 25 years ago), with the switch to using hashed databases and at the same time discarding the whitespace (which counted against the 1023 byte limit on termcap size). Since FreeBSD switched to using ncurses in the 1990s, that format is more out of date, with few applications relying on the TERMCAP variable. But ls is one of those.

screen does have an option -T which should help with this by specifying a particular termcap entry (which has color), but on testing it, appears that cannot solve the problem.

Further reading:

Related Question