0

I thought of playing around a bit with find -fprintf. In case you don't know what -fprintf does, it is the same as -printf but writing to a file you specify its name.

Now, when I run a command like this:

find -maxdepth 1 -type d  -fprintf output "%p\b\n"

I get the following in output (using vim and pretty much any text editor):

.^H
./directory-1^H
./directory-2^H
./directory-3^H

I understand that ^H is the backspace character. Opening output with less:

./directory-
./directory-
./directory-

So, the question is:

  1. Why do vim and other text editors (tried nano, and emacs) display the backspace without interpreting it by removing the character before it but less does?
  2. Why don't the editors print a character for \n instead of going down for a new line?
  3. What is the difference between printing a backspace and hitting backspace on the keyboard (a character gets actually deleted on hitting backspace on the keyboard)?

I'm running this on my machine (laptop) without sshing anywhere. Using GNU/Linux Ubuntu 16.04 LTS with konsole and tmux.

  • 3
    I think it's because less like more are pager and the others are editors. You can get the same display with less with the -U option. – ctac_ Oct 16 '18 at 20:28
  • Alright. Then why don't the editors print a character for \n instead of going down for a new line? And what is the difference between printing a backspace and hitting backspace on the keyboard (a character gets actually deleted on hitting backspace on the keyboard)? – joker Oct 17 '18 at 7:51
3

Why do vim and other text editors (tried nano, and emacs) display the backspace without interpreting it by removing the character before it but less does?

Why should they? FWIW, neither do browsers :-)

$ printf "<html>foo\bbar</html>" > /tmp/foo.html
$ firefox /tmp/foo.html

Should editors also interpret other kind of markup, like mini-Markdown *foo* or **bar**?

Notice that backspace isn't just "deleting" the previous char in less, but it's used as a crude formatting character. x\bx will print x in bold, and x\b_ will underline it (which on some terminals will cause it to be printed with a different color):

printf "H\b_e\b_r\b_e\b_'s\bs Johnny!" | less

Why don't the editors print a character for \n instead of going down for a new line?

They could do that. For instance, if you use :set list in vi, newlines will be printed as $ and tabs as ^I.

What is the difference between printing a backspace and hitting backspace on the keyboard (a character gets actually deleted on hitting backspace on the keyboard)?

On a hard-type terminal (printing on paper), printing a backspace was causing the carriage to go one position to the left, so a subsequent char would overwrite, not delete what was already on the paper. On glass (CRT) and emulated terminals, moving a position to the left and writing a character creates an 'erase' effect because overwriting a character replaces it completely. But the \b by itself does not remove anything: printf "123\b\n" will print 123 not 12.

The latter is a function of the tty driver, which interprets some input characters as editing/control commands (erase, werase, intr, kill -- look at the stty(1) or termios(3) manpages for the full list).

And the backspace key does not always generate a \b / ^H (BS) character. Most of the time is \x7f / ^? (DEL).

But you can set it to whatever you like:

$ stty erase @

Now hitting @ will erase the previous char, like in unix v7.

  • For the part regarding printing \n instead of going down for a new line. I understand that vim displays the \n as $ when :set list. The question is: why doesn't it display a\nb on a single terminal line with \n in the middle instead of going one line down? vim interprets \n as we are expecting it to, by moving down one line and not printing a character indicating the new line with the rest of the text around. – joker Oct 17 '18 at 10:31
  • because that's the user's expectation, to have text files displayed 2-dimensionally; but you can force vim to display the whole file on a single line by setting the newline separator to CR as on (older?) Macs with eg. :e ++ff=mac file – mosvy Oct 17 '18 at 10:42
1

File contents are what applications make of them.

One of the features of the design of Unix was that files are undistinguished sequences of characters, and it is up to applications to place whatever interpretation that they like upon them. Applications can and do interpret file contents differently, and you are experiencing the consequences of this.

VIM is interpreting the file contents in accordance with the Single Unix Specification's notion of a Text File, which is a file comprising zero or more lines terminated by and containing no characters. It turns unprintable characters into various printable representations, but is always the end of a line because that is part of the concept.

Other utilities interpret file contents differently. One family of them interprets file contents as a stream of Teletype Model 37 (TTY-37) output data. This family comprises several conventional Unix and GNU programs: less, more, most, ul, colcrt, ncal, grotty in non-default mode, and others. In this interpretation, the character moves the (conceptual) print head back one position and overstrikes what was there before. Because these programs are not physical TTY-37s with ink on paper, they implement their own ideas in software of what overstriking means. Overstriking can variously result in attempts to use boldface and underline attributes, in complete replacement of one character by another, in combined characters, or in nothing at all.

Further reading

  • Thanks mate for the clear answer. Needed to read that. – joker Dec 18 '18 at 14:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.