A EOL do Unix / Linux é LF, avanço de linha, ASCII 10, sequência de escape \n
.
Aqui está um trecho de código Python para obter exatamente um pressionamento de tecla:
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
Quando pressiono Entermeu teclado em resposta a esse trecho, ele fornece \r
retorno de carro, ASCII 13.
No Windows , Enterenvia CR LF == 13 10
. * nix não é Windows; por que Enterdar 13 em vez de 10?
Respostas:
Enquanto a resposta de Thomas Dickey é bastante correta, Stéphane Chazelas mencionou corretamente em um comentário à resposta de Dickey que a conversão não é imutável; faz parte da disciplina de linha.
De fato, a tradução é completamente programável.
A página do manual man 3 termios contém basicamente todas as informações pertinentes. (O link leva para o projeto de páginas de manual do Linux , que menciona quais recursos são apenas para Linux e são comuns ao POSIX ou a outros sistemas; sempre verifique a seção Conforming to em cada página.)
Os
iflag
atributos do terminal (old_settings[0]
no código mostrado na pergunta em Python ) possuem três sinalizadores relevantes em todos os sistemas POSIXy:INLCR
: Se definido, traduza NL para CR na entradaICRNL
: Se definido (eIGNCR
não estiver definido), traduza CR para NL na entradaIGNCR
: Ignorar CR na entradaDa mesma forma, também existem configurações de saída relacionadas (
old_settings[1]
):OPOST
: Ativar o processamento de saída.OCRNL
: Mapeie CR para NL na saída.ONLCR
: Mapeie NL para CR na saída. (XSI; não disponível em todos os sistemas POSIX ou Single-Unix-Specification.)ONOCR
: Ignore (não produza) CR na primeira coluna.ONLRET
: Ignorar (não produzir) CR.Por exemplo, você pode evitar confiar no
tty
módulo. A operação "makeraw" apenas limpa um conjunto de sinalizadores (e define oCS8
oflag):embora, para fins de compatibilidade, convém verificar se todas essas constantes existem primeiro no módulo termios (se você executar em sistemas não POSIX). Você também pode usar
new_settings[6][termios.VMIN]
enew_settings[6][termios.VTIME]
definir se uma leitura será bloqueada se não houver dados pendentes e por quanto tempo (em número inteiro de segundos decisivos). (Normalmente,VMIN
é definido como 0 eVTIME
0 se as leituras devem retornar imediatamente ou para um número positivo (décimo de segundos) quanto tempo a leitura deve esperar no máximo.)Como você pode ver, o acima (e "makeraw" em geral) desabilita toda a tradução na entrada, o que explica o comportamento que o gato está vendo:
Para obter um comportamento normal, omita as linhas que limpam essas três linhas e a conversão de entrada permanece inalterada, mesmo quando "bruta".
A
new_settings[1] = new_settings[1] & ~termios.OPOST
linha desativa todo o processamento de saída, independentemente do que dizem os outros sinalizadores de saída. Você pode simplesmente omiti-lo para manter intacto o processamento de saída. Isso mantém a saída "normal", mesmo no modo bruto. (Isso não afeta se a entrada é ecoada automaticamente ou não; isso é controlado peloECHO
cflag innew_settings[3]
.)Por fim, quando novos atributos são definidos, a chamada será bem-sucedida se alguma das novas configurações tiver sido definida. Se as configurações forem confidenciais - por exemplo, se você estiver solicitando uma senha na linha de comando -, deverá obter as novas configurações e verificar se os sinalizadores importantes estão definidos / desabilitados corretamente, para ter certeza.
Se você quiser ver as configurações atuais do terminal, execute
Os sinalizadores de entrada geralmente estão na quarta linha e os sinalizadores de saída na quinta linha, com um
-
nome anterior ao sinalizador, se o sinalizador estiver desmarcado. Por exemplo, a saída pode serNos pseudo-terminais e nos dispositivos USB TTY, a taxa de transmissão é irrelevante.
Se você escreve scripts Bash que desejam ler, por exemplo, senhas, considere o seguinte idioma:
A
EXIT
armadilha é executada sempre que o shell sai. Elestty -g
lê as configurações atuais do terminal no início do script, para que as configurações atuais sejam restauradas quando o script sair automaticamente. Você pode até interromper o script com Ctrl+ C, e ele fará a coisa certa. (Em alguns casos de canto com sinais, eu descobri que o terminal às vezes fica preso às configurações brutas / não-canônicas (exigindo que você digitereset
+ Entercegamente no terminal), mas a execuçãostty sane
antes de restaurar as configurações originais reais curou todas as vezes É por isso que está lá; uma espécie de segurança adicional.)Você pode ler as linhas de entrada (não associadas ao terminal) usando o
read
bash embutido ou até ler a entrada caractere a caractere usandoSe você não definir
IFS
como ASCII NUL, o internoread
consumirá os separadores, de modo quec
eles estarão vazios. Armadilha para jovens jogadores.fonte
Essencialmente "porque tem sido feito dessa maneira desde as máquinas de escrever manuais". Sério.
Uma máquina de escrever manual tinha uma carruagem na qual o papel era alimentado e avançava enquanto você digitava (carregando uma mola) e tinha uma alavanca ou chave que liberaria a carruagem, permitindo que a mola retornasse a carruagem à margem esquerda.
À medida que a entrada eletrônica de dados (teletipo, etc.) foi introduzida, eles a levaram adiante. Portanto, a Enterchave em muitos terminais seria rotulada Return.
As alimentações de linha ocorreram (no processo manual) após o retorno do carro à margem esquerda. Novamente, os dispositivos eletrônicos imitaram os dispositivos manuais, fazendo uma line-feedoperação separada .
Ambas as operações são codificadas (para permitir que o teletipo seja mais do que um dispositivo independente, criando um tipo de papel), então temos
CR
(retorno de carro) eLF
(alimentação de linha). Esta imagem do Teletype Information do ASR 33 mostra o teclado, comReturn
o lado direito eLine-Feed
logo à esquerda. Estar à direita , era a chave principal:O Unix apareceu mais tarde. Seus desenvolvedores gostavam de encurtar as coisas (veja todas as abreviações, mesmo
creat
para "criar"). Diante de um processo possivelmente em duas partes, eles decidiram que os feeds de linha só faziam sentido se fossem precedidos por retornos de carro. Então, eles retiraram os retornos de carro explícitos dos arquivos e converteram a Returnchave do terminal para enviar o feed de linha correspondente. Apenas para evitar confusão, eles se referiram ao feed de linha como "nova linha".Ao escrever texto no terminal, o Unix se traduz na outra direção: um avanço de linha se torna retorno de carro / avanço de linha.
(Ou seja, "normalmente": o chamado "modo cozido", em contraste com o modo "bruto", onde nenhuma tradução é feita).
Resumo:
fonte
LF
é traduzida paraCR LF
. Quando você digitafoo<Return>
no modo cozido, o aplicativo lêfoo\n
efoo\r\n
é enviado de volta pela disciplina de linha para eco no terminal.