3

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)?

  • 1
    hex it and see!! – zee May 23 '17 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 '17 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 '17 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 '17 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 '17 at 0:46
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.

| improve this answer | |
2

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).

| improve this answer | |
  • 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 '17 at 16:07
  • yes (though <kbd>*Enter*</kbd> normally is not configurable, so "By default" is redundant). – Thomas Dickey May 23 '17 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 at 7:26

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.