Una variable sin comillas (como en $var) o una sustitución de comando (como en $(cmd)o `cmd`) es el operador split + glob en shells tipo Bourne.
Es decir, su contenido se divide de acuerdo con el valor actual de la $IFSvariable especial (que por defecto contiene el espacio, la pestaña y los caracteres de nueva línea)
Y luego cada palabra resultante de esa división está sujeta a la generación de nombre de archivo (también conocido como expansión global o de nombre de archivo ), es decir, se consideran patrones y se expanden a la lista de archivos que coinciden con ese patrón.
Entonces for i in $(xrandr), el $(xrandr), porque no está entre comillas, se divide en secuencias de caracteres de espacio, tabulación y nueva línea. Y cada palabra resultante de esa división se verifica para buscar nombres de archivo coincidentes (o se deja como está si no coinciden con ningún archivo), y se forrepite sobre todos ellos.
En for i in "$(xrandr)", no estamos utilizando el operador split + glob como se cita la sustitución del comando , por lo que hay un pase en el bucle en un valor: la salida de xrandr(sin los caracteres de nueva línea que ordenan las tiras de sustitución del comando ).
Sin embargo echo $i, en , $ino se vuelve a citar, por lo que nuevamente el contenido de $ise divide y está sujeto a la generación de nombre de archivo y se pasan como argumentos separados al echocomando (y echogenera sus argumentos separados por espacios).
Entonces, la lección aprendida:
- si no desea la división de palabras o la generación de nombre de archivo , siempre cite expansiones variables y sustituciones de comandos
- si desea la división de palabras o la generación de nombre de archivo , déjelas sin comillas pero configúrelas en
$IFSconsecuencia y / o habilite o deshabilite la generación de nombre 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ía:
- dejar
$IFSen su valor predeterminado (o desarmarlo) para dividir en espacios en blanco
- Uso
set -fde generar nombres de archivos deshabilitar menos que esté seguro de que xrandrno emite ninguna *o ?o [caracteres (que se utilizan caracteres comodín en patrones de generación de nombre de archivo)
Y luego solo use el operador split + glob (solo deje la sustitución del comando o la expansión variable sin comillas) en la inparte del forbucle:
set -f; unset -v IFS
for i in $(xrandr); do whatever with "$i"; done
Si desea recorrer las líneas (no vacías) de la xrandrsalida, deberá establecer $IFSel carácter de nueva línea:
IFS='
'