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 $IFS
variable 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 for
repite 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 , $i
no se vuelve a citar, por lo que nuevamente el contenido de $i
se divide y está sujeto a la generación de nombre de archivo y se pasan como argumentos separados al echo
comando (y echo
genera 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
$IFS
consecuencia 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
$IFS
en su valor predeterminado (o desarmarlo) para dividir en espacios en blanco
- Uso
set -f
de generar nombres de archivos deshabilitar menos que esté seguro de que xrandr
no 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 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) de la xrandr
salida, deberá establecer $IFS
el carácter de nueva línea:
IFS='
'