What determines whether backspaces show up in a file created with cat

catcontrol-charactersio-redirectiontty

I just noticed that I've seen different behavior across different systems when creating a quick test file (e.g. with sample input) via cat and redirection.

Here are the steps to see what I'm talking about:

Run cat > testfile.

Type in helli, then press backspace, then type o.

Press Enter.

Type Ctrl-D to end the input.

Run od -a testfile.

On some systems, e.g. Mac, you will get:

0000000    h   e   l   l   o  nl                                        
0000006

On other systems, e.g. a RHEL 5.7 host that I logged into via MobaXterm on Windows, you may get:

0000000    h   e   l   l   i  bs   o  nl                                        
0000010

Where is the code that makes for this difference? For example, in the example above, should I suspect MobaXterm, or the RHEL 5 system? Or which layer between my keyboard and the filesystem?


This is more a question out of curiosity than a real problem; I can obviously create files without the backspace characters by just using a text editor, but this has tripped me up in the past. One time during a casual presentation/training, I mentioned that creating files via cat has this problem with backspace characters being taken literally, only to be shown wrong when it didn't have that effect after all, on the Macs the students were using. So it got me curious.

Best Answer

That's determined by a) what characters does the terminal emulator send when the BackSpace key is pressed (^H/BS or ^?/DEL) and b) what character is used as VERASE by the tty driver (see and change the latter with stty(1) -- stty erase ^H).

If the terminal emulator is sending ^H but the tty isn't recognizing it as a special character, presssing the BackSpace key will visually "erase" the last character on the screen[1], but the character will be sent as-is (together with the character before it) to the process reading from the tty (cat).

Editors and interactive programs with line-editing capabilities set the tty to raw mode and do their own handling of special characters, and may treat ^H and ^? the same; cat isn't one of those ;-)

[1] this is subject to the echoctl stty setting -- if that is set, the terminal will echo control characters back in the "^"+chr(char^0x40) format (^H for BS = 8, etc).

Related Question