4

I opened two terminals, and from the below terminal I executed cat to read from the above terminal:

enter image description here

In the above terminal I type "Hello World<Enter>Bye", but looks like the above terminal sent the Enter key as a carriage return (\r).

So does bash changes the settings of the terminal to make it translates a newline (\n) to a carriage return (\r)?

8
  • 1
    hex it and see!!
    – z atef
    May 23, 2017 at 3:59
  • stty -a should give a complete list of what the terminal settings are. In particular, the settings for inlcr igncr icrnl determine what the terminal does with CR-NL translation on input and the corresponding o flags tell what happens on output. Thomas DIckey's answer below explains how bash sets those flags in detail.
    – NickD
    May 23, 2017 at 20:21
  • @Nick Does "on input" mean when the terminal send something to bash , and "on output" mean when bash send something to the terminal?
    – paul
    May 23, 2017 at 23:18
  • It means when the terminal sends something to the kernel. Similarly for output. Basically, user space tells the kernel how it wants terminal IO to be handled and the kernel obliges.
    – NickD
    May 24, 2017 at 0:42
  • @Nick "on input" means when the terminal sends something to the kernel/tty device, and "on input" means when the bash sends something to the kerne/tty devicel?
    – paul
    May 24, 2017 at 0:46

2 Answers 2

4

Bash has changed the terminal to "raw" mode, which means typer characters are not processed in any way. The enter key produces a Carriage Return character (\r), not a Line Feed (\n), so no translation takes place.

3

raw and cooked modes are descriptive terms. stty raw uses different settings than bash.

Bash does terminal initialization in prepare_terminal_settings (an internal function of the readline library), setting the terminal mode to allow reading a single character at a time without echoing:

  tiop->c_lflag &= ~(ICANON | ECHO);

however, the carriage-return translation is reset in a different part of the function:

  /* Make sure we differentiate between CR and NL on input. */
  tiop->c_iflag &= ~(ICRNL | INLCR);

If you compare prepare_terminal_settings to the coreutils stty, the latter does less (several points, but bash resets INLCR as well):

      else if (STREQ (info->name, "raw") || STREQ (info->name, "cooked"))
        {
          if ((info->name[0] == 'r' && reversed)
              || (info->name[0] == 'c' && !reversed))
            {
              /* Cooked mode. */
              mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
              mode->c_oflag |= OPOST;
              mode->c_lflag |= ISIG | ICANON;
#if VMIN == VEOF
              mode->c_cc[VEOF] = CEOF;
#endif
#if VTIME == VEOL
              mode->c_cc[VEOL] = CEOL;
#endif
            }
          else
            {
              /* Raw mode. */
              mode->c_iflag = 0;
              mode->c_oflag &= ~OPOST;
              mode->c_lflag &= ~(ISIG | ICANON
#ifdef XCASE
                                 | XCASE
#endif
                );
              mode->c_cc[VMIN] = 1;
              mode->c_cc[VTIME] = 0;
            }
        }

POSIX says of stty raw:

Enable (disable) raw input and output. Raw mode shall be equivalent to setting:

stty cs8 erase ^- kill ^- intr ^- \
    quit ^- eof ^- eol ^- -post -inpck

which interestingly enough (following the descriptions of -post and -inpck) does not address carriage return translation on input.

Since the terms raw and cooked (either POSIX or coreutils stty) do not correspond to what bash does, mentioning the POSIX termios features that correspond to what it actually does are the way to go: icrnl (input carriage-return to newline translation).

3
  • Let me see if I understand this. By default the terminal process (for example: gnome-terminal, xterm, etc.) sends a CR to the tty device when you press Enter, but the tty device has a default setting to translate the CR to a LF, but now when bash runs it modifies this tty device setting to make it not translate the CR to a LF. Am I correct?
    – paul
    May 23, 2017 at 16:07
  • yes (though <kbd>*Enter*</kbd> normally is not configurable, so "By default" is redundant). May 23, 2017 at 20:02
  • It's useful, though, because on virtual terminals what character the key causes to be transmitted is configurable, via a keyboard map.
    – JdeBP
    Apr 17, 2020 at 7:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .