I guess by “enter” you mean the Return key of your keyboard,
probably labeled ↵.
Short answer:
The reason why putty, minicom and screen send CR when you hit
Return is because the Return key actually means
“Carriage return” (CR).
The reason why echo
and printf("Hello, world!\n");
send LF is
because they end their output with \n
, which means LF. Note that these
programs do not hit a Return key: they do not even touch a
keyboard.
Long answer:
Back in the seventies, we were transitioning from ttys to CRT-based
computer terminals. Early terminals had keyboards with separate keys for
CR and LF. On the DEC VT05, these were labeled, quite appropriately,
CR and LF. On the VT50 and VT100 series,
they were labeled RETURN and LINE FEED. Later
models dropped the LINE FEED key and we ended up with
Return and no key for LF. Nowadays, these bulky terminals
have been replaced by terminal emulators such as rxvt or gnome-terminal.
However, as the name implies, a terminal emulator's job is… to emulate a
terminal! Thus, the situation hasn't changed that much: the
Return key still stands for CR, just as it did in 1975.
On the other hand, Unix standardized on using LF as the end-of-line
indicator. Both in text files and in user-space programs, lines of text
are always terminated by LF. This begs the question: how do we then
interact with a Unix system using a terminal that makes sending LF a lot
harder than sending CR? The answer is… it depends on what specific
program we are interacting with.
When we interact with a “naive” program, or rather a program that
doesn't bother to handle the terminal, the in-kernel terminal driver is
in “canonical” (or “cooked”) mode. In this mode, it translates the CR
characters coming from the terminal to LF, and the outgoing LFs to CR+LF
sequences. These translations can be seen as the icrnl
and onlcr
flags in the output of stty -a
.
Some programs prefer to handle the terminal themselves: they instruct
the terminal driver to refrain from doing character
conversions (they set it to “raw” mode) and handle these conversions
themselves. Most often this is done within a library such as
readline or ncurses. Bash is one of those programs (it uses
readline) but, thankfully, it resets the terminal to cooked mode before
exec()
-ing other programs.
Now, imagine you want to talk to some sort of device that speaks text on
a serial port. You go to your attic and grab your old VT420 that has
been collecting dust there for almost 30 years. You hook it to your
device using a cross-over (“null-modem”) cable, and voilà! Your device
has a terminal! How cool is that? Hopefully, this device has been
designed to play nicely with a classic terminal: it expects
CR-terminated messages. If it expected LF instead, then you would have
to end your lines by typing Ctrl-J, as the VT420
has no dedicated LINE FEED key.
If you don't own any of these lovely vintage terminals, you can use
instead an emulated one such as gnome-terminal or cool-retro-term.
You connect it to your device using a communication program such as
minicom, or picocom, and a USB-to-serial converter. In their default
configuration, these communication programs do not mess with your data
stream: they configure the tty driver in raw mode (on both ends), and
they forward the bytes faithfully between your emulated terminal and
your device, just like the null-modem cable would do with your VT420.
But unlike a null-modem cable, picocom can be configured to translate
the line endings on the fly if needed.
stty -a
. Usestty -ocrnl
to change the output behaviour of CR being translated to LF.