Em um shell Linux, por que a barra invertida-newline não introduz espaços em branco?

4

Ao usar o shell do Linux, me deparo com a seguinte situação:

$ A=B\
> C
$ echo $A
BC

Na minha opinião, quando a nova linha encontra um caractere de escape, ela não pode ser um personagem de CR, mas ainda pode ser uma nova linha. O echo $Adeve ser interpretado como echo B newline Ce a nova linha deve ser um IFS para echo. Portanto, a saída deve ser em B Cvez de BC.

Por que obtenho a saída que recebo?

user3872279
fonte
Olá, usuário3872279. Editei sua pergunta um pouco principalmente para formatação (para enfatizar qual é a sua pergunta) e alterei o título para ser mais descritivo. Se você sentir que eu mudei de intenção, sinta-se à vontade para reverter a edição ou editar você mesmo.
um CVn
@ MichaelKjörling De fato, por causa do inglês ruim, não consigo descrever o que quero perguntar de uma maneira elegante. Compreendo que você tenha o que está em minha mente e muito obrigado!
user3872279

Respostas:

5

Citação man bash, seção CITAÇÃO :

Uma barra invertida não citada ( \) é o caractere de escape. Ele preserva o valor literal do próximo caractere a seguir, com exceção de <newline>. Se um \<newline>par aparecer e a barra invertida não for citada, ela \<newline>será tratada como uma continuação de linha (ou seja, será removida do fluxo de entrada e efetivamente ignorada).

Isso permite que você quebre comandos muito longos / sequências de comandos (canalizando e transformando a saída etc.) em scripts em várias linhas para facilitar a leitura.


Para que ele trate a nova linha conforme o esperado, basta agrupar o valor (e qualquer uso posterior da variável) entre aspas.

$ A="B
> C"
$ echo "$A"
B
C

Da mesma seção:

Incluir caracteres entre aspas simples preserva o valor literal de cada caractere dentro das aspas. ...

A inclusão de caracteres entre aspas duplas preserva o valor literal de todos os caracteres entre aspas, com exceção de $, ` \, e, quando a expansão do histórico está ativada,!. Os caracteres $ e `mantêm seu significado especial entre aspas duplas. A barra invertida mantém seu significado especial somente quando seguido por um dos seguintes caracteres: $, `," \, ou.

Daniel Beck
fonte
1

Respondendo o "porquê" como "por que isso é útil":

A barra invertida-nova linha é usada para a continuação de linha para dividir linhas longas ovely:

Uma barra invertida no final de uma linha em um script de shell faz com que o shell ignore a nova linha para fins de execução do script. Isso normalmente é usado para dividir linhas longas em um arquivo de script em várias linhas de texto, que serão manipuladas como uma única linha de script pelo shell.

Por exemplo, o comando

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD --graph --decorate --pretty=oneline --simplify-by-decoration

pode ser escrito como

git log --tags --branches HEAD FETCH_HEAD ORIG_HEAD \
    --graph --decorate --pretty=oneline --simplify-by-decoration
Volker Siegel
fonte
0
A=B\
C

significa "A é igual à string B, seguida por uma nova linha que estou ignorando, seguida por um C"

Não há CR no que você digitou, na medida em que o shell o vê. O fim de linha do Linux / Unix é um feed de linha (LF), não CR. O CR é emitido como parte do manuseio do terminal. A maioria dos terminais precisa de um avanço de linha para descartar uma linha e um retorno de carro para enviar o cursor de volta para a esquerda. O CR é inserido pelo kernel, ao enviar um Line Feed para o terminal, quando o terminal precisa disso - IOW, ele não é visível para o shell. Observe que, por exemplo, um editor visual pode separar o uso de CR e LF - o menor número de caracteres para a próxima parte da tela a ser reescrita pode envolver um LF (para ir direto para a página sem alterar a coluna).

Um pouco mais confuso, também há uma tradução de entrada para teclados. A tecla Enter geralmente envia um retorno de carro (Control-M). Mas, para reconhecer que um comando foi inserido, o shell precisa ver um Fim de Linha. Um sttyparâmetro adicional descreve, portanto, para o tratamento do terminal do kernel, que um CR de entrada deve ser convertido em um fim de linha. Portanto, o shell ainda não vê um CR.

O resultado final é que o terminal envia:

A=B\<CR>C<CR>

O shell recebe:

A=B\<LF>C<LF>

O shell analisa isso como "oh, nova linha de barra invertida - eu simplesmente ignoro isso" e termina com:

A=BC<LF>

E na saída, o kernel modifica a sequência enviada ao terminal durante a entrada do comando como:

A=B\<CR><LF>C<CR><LF>

O processamento de núcleo de manipulação do terminal é gerido pelo comando shell sttye dependendo da implementação (Linux, Mac OS X, * BSD), subjacente detalhes devem estar sob man termios, man tty_ioctl. man console_ioctletc.

JezC
fonte
Você tem algum material recomendado para eu saber mais sobre a tradução de entrada para teclados e " O CR é inserido pelo kernel, ao enviar um Feed de Linha ao terminal, quando o terminal precisa disso - IOW, não é visível para o shell . "
user3872279 11/11/14