11 votos

En un shell de Linux, ¿por qué la barra invertida-nueva línea no introduce espacio en blanco?

Cuando uso la terminal de Linux, me encuentro con la siguiente situación:

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

En mi opinión, cuando el carácter de escape encuentra un salto de línea, no puede ser un carácter CR pero sigue siendo un salto de línea. El echo $A debería interpretarse como echo B salto de línea C y el salto de línea debería ser un IFS para echo. Entonces la salida debería ser B C en lugar de BC.

¿Por qué obtengo la salida que obtengo?

1 votos

Hola usuario3872279. He editado ligeramente tu pregunta principalmente para dar formato (para resaltar cuál es tu pregunta) y cambié el título para que sea más descriptivo. Si sientes que cambié tu intención de alguna manera, siéntete libre de deshacer la edición, o editar aún más tú mismo.

0 votos

@MichaelKjörling De hecho, debido a mi mal inglés, no puedo describir de manera elegante lo que quiero preguntar. Aprecio que hayas entendido lo que pasa por mi mente ¡Muchas gracias!

11voto

Daniel Beck Puntos 72548

Citando man bash, sección CITAS:

Una barra invertida no citada (\) es el carácter de escape. Preserva el valor literal del siguiente carácter que sigue, con la excepción de . Si aparece un par de \, y la barra invertida no está citada, el \ se trata como una continuación de línea (es decir, se elimina del flujo de entrada y se ignora efectivamente).

Esto te permite dividir comandos muy largos / secuencias de comandos (tuberías y transformaciones de salida, etc.) en scripts en múltiples líneas para mejorar la legibilidad.


Para que trate el salto de línea como esperas, simplemente envuelve el valor (y cualquier uso posterior de la variable) entre comillas.

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

De la misma sección:

Encerrar caracteres entre comillas simples preserva el valor literal de cada carácter dentro de las comillas. ...

Encerrar caracteres entre comillas dobles preserva el valor literal de todos los caracteres dentro de las comillas, con la excepción de $, `, \, y, cuando está habilitada la expansión de historial, !. Los caracteres $ y ` mantienen su significado especial dentro de comillas dobles. La barra invertida conserva su significado especial solo cuando le sigue uno de los siguientes caracteres: $, `, ", \, o ..

6voto

Volker Siegel Puntos 742

Respondiendo al "por qué" como "¿por qué es esto útil?":

La barra invertida-segunda línea se utiliza para continuación de línea para dividir líneas excesivamente largas:

Una barra invertida al final de una línea en un script de shell hace que el shell ignore la nueva línea con el propósito de ejecutar el script. Normalmente se usa para dividir líneas largas en un archivo de script en múltiples líneas de texto, las cuales serán manejadas como una sola línea de script por el shell.

Por ejemplo, el comando

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

puede escribirse como

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

4voto

Code-Read Puntos 101

Advertencia: la barra invertida continúa una línea solo si es el último carácter en la línea.

Esto es un poco fuera de tema; lo agrego aquí como un problema fácil de pasar por alto. Si termina involuntariamente una línea en su script de shell con \ (barra invertida seguida de espacio o tabulación) en lugar de \ es posible que su script se detenga o se comporte de manera inesperada aunque la barra invertida aparezca ser el último carácter.

Si está editando con vi es fácil detectar este problema con el comando :set list, que colocará un $ al final de cada línea, permitiéndole detectar espacios o tabulaciones al final. :set nolist apaga esta característica de vi.

0voto

JezC Puntos 510
A=B\
C

significa "A es igual a la cadena B, seguido de un salto de línea que estoy ignorando, seguido de una C"

No hay CR en lo que has escrito, por lo que el shell lo ve. El final de línea de Linux/Unix es un salto de línea (LF), no CR. El CR se emite como parte del manejo del terminal. La mayoría de los terminales necesitan un salto de línea para bajar una línea y un retorno de carro para enviar el cursor de vuelta a la izquierda. El CR es insertado por el kernel cuando envía un salto de línea al terminal, cuando el terminal lo necesita; es decir, no es visible para el shell. Ten en cuenta que, por ejemplo, un editor visual puede separar el uso de CR y LF: los pocos caracteres hasta la próxima parte de la pantalla que se debe reescribir pueden involucrar un LF (para bajar de manera recta por la página sin cambiar de columna).

Un poco más confuso, también hay una traducción de entrada para los teclados. La tecla Enter normalmente envía un retorno de carro (Control-M). Pero para reconocer que se ha introducido un comando, el shell necesita ver un final de línea. Un parámetro adicional de stty describe por tanto al manejo de terminal del kernel que un CR de entrada debe ser traducido a un final de línea. Por lo tanto, el shell sigue sin ver un CR.

El resultado final es que el terminal envía:

A=B\C

El shell recibe:

A=B\C

El shell interpreta eso como "oh, barra invertida y salto de línea - simplemente ignoro eso" y termina con:

A=BC

Y en la salida el kernel modifica la secuencia enviada al terminal durante la entrada de comandos como:

A=B\C

El manejo del kernel del terminal es gestionado por el comando del shell stty y dependiendo de la implementación (Linux, Mac OS X, *BSD), los detalles subyacentes deben encontrarse en man termios, man tty_ioctl, man console_ioctl, etc.

0 votos

¿Tienes algún material recomendado para que pueda saber más sobre la traducción de entrada para teclados y "El CR es insertado por el kernel cuando envía un salto de línea al terminal, cuando el terminal lo necesita, es decir, no es visible para el shell."

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X