Ssh – Line endings when using GNU Screen

gnu-screenssh

I'm seeing some slightly odd behaviour when using GNU Screen 4.00.03 on a Red Hat Enterprise Linux 6.4 system.

If I connect without Screen, looking at the logs I can see each line is terminated with CRLF (0x0D 0x0A), exactly as expected.

If I connect and run Screen, lines with two or more characters are terminated with CRLF as expected. Lines with no printed characters (eg from running a bare echo) are terminated only with LF (0x0A), and most bizarrely of all, lines with a single printed character (eg echo x) are terminated with BSLF (0x08 0x0A).

I'm seeing this with PuTTY, and the above logs are from PuTTY logs. I'm also seeing this with automated Python frameworks using Pexpect, so I'm not blaming PuTTY for this.

What's going on? How do I stop it?

Best Answer

That's an optimisation done by screen.

When you type echo<Cr> in screen. Because of the local echo and the icrnl and onlcr settings of the pseudo terminal device in the screen window, the \r\n sequence is sent to master side (to screen).

screen implements a terminal emulator where \r is meant to bring the cursor to the beginning of the line and \n to move the cursor down. To do that, where a terminal emulator like xterm would do X API calls to move the cursor to the beginning of the line, screen has to send escape codes to the host terminals it is attached to to tell it/them to move the cursor to the left hand side of the screen window.

In case you've split the window vertically, that means send cursor positioning escape sequences to wherever the left hand side of the screen windows is. If not or if on the left hand side of the host terminal, screen would just pass those \r and \n characters along so that the cursor be moved to the beginning of the line and one line down on the host terminal as well (since all terminals treat \r and \n the same in that instance).

Now, echo runs and outputs a \n character. Because of onlcr again in the screen window tty, screen receives \r\n again. \r tells it to move to the beginning of the line, but the cursor is already at the beginning of the line, so no need to do anything which is why the host terminal doesn't receive a second \r character. Then to move the cursor down because of the \n it receives, screen sends \n to the host terminal.

You can verify that by running in screen:

printf '\r\r\r\r'

You'll notice that screen only sends one \r character to its host terminal.