¿Cuál es el significado exacto de IFS = $ ‘\ n’?

Si el siguiente ejemplo, establece la variable de entorno IFS en un carácter de avance de línea …

 IFS=$'\n' 
  • ¿Qué significa exactamente el signo de dólar ?
  • ¿Qué hace en este caso específico?
  • ¿Dónde puedo leer más sobre este uso específico (Google no permite caracteres especiales en las búsquedas y, de lo contrario, no sé qué buscar)?

Sé lo que es la variable de entorno IFS , y cuál es el carácter \n (línea de alimentación), pero ¿por qué no usar la siguiente forma: IFS="\n" (que no funciona)?

Por ejemplo, si quiero recorrer cada línea de un archivo y quiero usar un ciclo for, podría hacer esto:

 for line in (< /path/to/file); do echo "Line: $line" done 

Sin embargo, esto no funcionará correctamente a menos que IFS esté configurado para un carácter de avance de línea. Para que funcione, tendría que hacer esto:

 OLDIFS=$IFS IFS=$'\n' for line in (< /path/to/file); do echo "Line: $line" done IFS=$OLDIFS 

Nota: no necesito otra forma de hacer lo mismo, ya conozco a muchos otros … Solo tengo curiosidad sobre ese $'\n' y me pregunté si alguien podría darme una explicación al respecto.

Normalmente bash no interpreta secuencias de escape en literales de cadena. Entonces, si escribe \n o "\n" o '\n' , no se trata de un salto de línea: es la letra n (en el primer caso) o una barra invertida seguida de la letra n (en los otros dos casos).

$'somestring' es una syntax para literales de cadenas con secuencias de escape . Entonces, a diferencia de '\n' , $'\n' realidad es un salto de línea.

De http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :

Las palabras con el formato “$ ‘STRING'” se tratan de manera especial. La palabra se expande a una cadena, con caracteres de escama invertida reemplazados como lo especifica el estándar ANSI-C. Secuencias de escape de barra invertida se pueden encontrar en la documentación de Bash.

Supongo que está obligando a la secuencia de comandos a escapar de la línea de alimentación al estándar ANSI-C adecuado.

Solo para darle al constructo su nombre oficial : las cadenas de la forma $'...' se llaman cadenas ANSI C-citadas .

Es decir, como en las cadenas [ANSI] C, las secuencias de escape de congulplpe se reconocen y expanden a su equivalente literal (ver más abajo la lista completa de secuencias de escape admitidas).

Después de esta expansión, $'...' cadenas $'...' comportan del mismo modo que '...' cadenas '...' , es decir, se tratan como literales NO sujetas a expansiones de shell [adicionales] .

Por ejemplo, $'\n' expande a un carácter de nueva línea literal, que es algo que un literal de cadena bash regular (ya sea '...' o "..." ) no puede hacer. [1]

Otra característica interesante es que las cadenas ANSI C-citadas pueden escapar ' (comillas simples) como \' , que '...' (cadenas simples entre comillas) no puede:

 echo $'Honey, I\'m home' # OK; this cannot be done with '...' 

Lista de secuencias de escape compatibles :

Las secuencias de escape de barra invertida, si están presentes, se decodifican de la siguiente manera:

\ a alerta (campana)

\ b retroceso

\ e \ E un carácter de escape (no ANSI C)

\ f formulario de alimentación

\ n nueva línea

retorno de carro

\ t pestaña horizontal

\ v pestaña vertical

\ backslash

\’ una frase

\ “doble cita

\ nnn el carácter de ocho bits cuyo valor es el valor octal nnn (de uno a tres dígitos)

\ xHH el carácter de ocho bits cuyo valor es el valor hexadecimal HH (uno o dos dígitos hexadecimales)

\ uHHHH el carácter Unicode (ISO / IEC 10646) cuyo valor es el valor hexadecimal HHHH (de uno a cuatro dígitos hexadecimales)

\ UHHHHHHHH el carácter Unicode (ISO / IEC 10646) cuyo valor es el valor hexadecimal HHHHHHHH (de uno a ocho dígitos hexadecimales)

\ cx un personaje de control-x

El resultado ampliado se cita por separado, como si el signo de dólar no hubiera estado presente.


[1] Sin embargo, puede incrustar nuevas líneas reales en cadenas ‘…’ y “…”; es decir, puede definir cadenas que abarcan varias líneas.

Recuperando el IFS predeterminado, este OLDIFS=$IFS no es necesario. Ejecute IFS nuevo en subshell para evitar anular el IFS predeterminado:

 ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} ) 

Además, realmente no creo que recuperes completamente el antiguo IFS. Debería OLDIFS="$IFS" para evitar el corte de líneas como OLDIFS="$IFS" .

ANSI C-entre comillas es un punto clave. Gracias a @ mklement0.

Puede probar cadenas ANSI C-citadas con el comando od.

 echo -n $'\n' | od -c echo -n '\n' | od -c echo -n $"\n" | od -c echo -n "\n" | od -c 

Productos:

 0000000 \n 0000001 0000000 \ n 0000002 0000000 \ n 0000002 0000000 \ n 0000002 

Puedes conocer el significado claramente por los resultados.

Es como recuperar el valor de una variable:

 VAR='test' echo VAR echo $VAR 

son diferentes, por lo que el signo de dólar básicamente evalúa el contenido.