GNU/Linux >> Tutoriales Linux >  >> Linux

¿Expansión de cadenas entre comillas y sin comillas?

  1. for i in $(xrandr); do echo "$i" ; done
  2. for i in "$(xrandr)"; do echo "$i"; done
  3. for i in "$(xrandr)"; do echo $i; done

Entiendo por qué 1 difiere de 2. Pero, ¿por qué 3 da un resultado diferente de 2? Por favor explique la salida también. ¿Cómo funcionan las comillas en las líneas nuevas?

Respuesta aceptada:

Una variable sin comillas (como en $var ) o sustitución de comandos (como en $(cmd) o `cmd` ) es el split+glob operador en shells tipo Bourne.

Es decir, su contenido se divide según el valor actual de $IFS variable especial (que por defecto contiene los caracteres de espacio, tabulación y nueva línea)

Y luego, cada palabra resultante de esa división está sujeta a generación de nombre de archivo (también conocido como globbing o expansión de nombre de archivo ), es decir, se consideran patrones y se expanden a la lista de archivos que coinciden con ese patrón.

Entonces en for i in $(xrandr) , el $(xrandr) , debido a que no está entre comillas, se divide en secuencias de espacios, tabuladores y caracteres de nueva línea. Y cada palabra resultante de esa división se verifica para buscar nombres de archivos coincidentes (o se deja como está si no coinciden con ningún archivo), y for recorre todos ellos.

En for i in "$(xrandr)" , no estamos usando el operador split+glob como sustitución de comando se cita, por lo que hay un paso en el bucle en uno valor:la salida de xrandr (sin los caracteres de nueva línea finales que comandan la sustitución tiras).

Sin embargo, en echo $i , $i no está entre comillas nuevamente, por lo que nuevamente el contenido de $i está dividido y sujeto a generación de nombre de archivo y esos se pasan como argumentos separados al echo comando (y echo genera sus argumentos separados por espacios).

Así que lección aprendida:

  • si no desea división de palabras o generación de nombre de archivo , siempre cite expansiones de variables y sustituciones de comandos
  • si desea división de palabras o generación de nombre de archivo , déjelos sin comillas pero establezca $IFS en consecuencia y/o habilite o deshabilite la generación de nombres de archivo si es necesario (set -f , set +f ).

Por lo general, en su ejemplo anterior, si desea recorrer la lista de palabras separadas en blanco en la salida de xrandr , necesitarías:

  • dejar $IFS en su valor predeterminado (o desactívelo) para dividir en espacios en blanco
  • Utilice set -f para deshabilitar la generación de nombres de archivo a menos que esté seguro de que xrandr nunca genera ningún * o ? o [ caracteres (que son comodines utilizados en los patrones de generación de nombres de archivo)
Relacionado:Db2:¿buscar la cadena de conexión para una base de datos DB2?

Y luego solo use el operador split+glob (solo deje la sustitución de comando o la expansión variable sin comillas) en in parte del for bucle:

set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done

Si desea recorrer las líneas (no vacías) del xrandr salida, necesitaría configurar $IFS al carácter de nueva línea:

IFS='
'

Linux
  1. ¿Número de archivos que contienen una cadena determinada?

  2. ¿Reemplazo de cadenas usando un diccionario?

  3. ¿Es `~#` una expansión tilde de Bash?

  4. Cómo dividir una cadena en Bash Script

  5. in_addr_t a cadena

Bash concatenar cadenas

Cómo verificar si una cadena contiene una subcadena en Bash

Sustitución de cadena en Bash

Bash Scripting – Manipulación de cadenas

información editada

¿Cómo agrego una variable a este comando curl?