O bash faz o terminal traduzir uma nova linha (\ n) para um retorno de carro (\ r)?

2

Eu abri dois terminais, e do terminal abaixo eu executei cat para ler o terminal acima:

Noterminalacimaeudigito"Hello World<Enter>Bye" , mas parece que o terminal acima enviou a chave Enter como um retorno de carro ( \r ).

O bash altera as configurações do terminal para fazer com que ele traduza uma nova linha ( \n ) para um retorno de carro ( \r )?

    
por paul 23.05.2017 / 04:20

2 respostas

3

O Bash mudou o terminal para o modo "raw", o que significa que os caracteres typer não são processados de forma alguma. A chave de entrada produz um caractere de retorno de carro (\ r), não um avanço de linha (\ n), portanto, nenhuma tradução ocorre.

    
por 23.05.2017 / 06:10
2
Os modos

raw e cooked são descritivos. stty raw usa configurações diferentes do bash.

O Bash faz a inicialização do terminal em prepare_terminal_settings ( uma função interna da biblioteca readline), configurando o modo terminal para permitir a leitura de um único caractere de cada vez sem ecoar:

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

no entanto, a tradução de retorno de carro é redefinida em um parte diferente da função :

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

Se você comparar prepare_terminal_settings com o coreutils stty , o último faz menos (vários pontos, mas o bash redefine INLCR também):

      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 diz de 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

que curiosamente (seguindo as descrições de -post e -inpck ) não aborda a tradução de retorno de linha na entrada.

Como os termos raw e cooked (POSIX ou coreutils stty) não correspondem ao que o bash faz, mencionando os recursos POSIX termios que correspondem ao que realmente faz é o caminho a percorrer: icrnl ( transporte de entrada-retorno para nova linha de tradução ).

    
por 23.05.2017 / 10:51