for i in $(xrandr); do echo "$i" ; donefor i in "$(xrandr)"; do echo "$i"; donefor i in "$(xrandr)"; do echo $i; done
Entiendo por qué 1 difiere de 2. Pero ¿por qué 3 da una salida diferente de 2? Por favor explique la salida también. ¿Cómo funcionan las citas en las nuevas líneas?

Respuestas:
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 seforrepite 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 dexrandr(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 alechocomando (yechogenera sus argumentos separados por espacios).Entonces, la lección aprendida:
$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:$IFSen su valor predeterminado (o desarmarlo) para dividir en espacios en blancoset -fde generar nombres de archivos deshabilitar menos que esté seguro de quexrandrno 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 delforbucle:Si desea recorrer las líneas (no vacías) de la
xrandrsalida, deberá establecer$IFSel carácter de nueva línea:fuente
Una nueva línea citada es una nueva línea. Entonces
echo "$1"da un argumento de línea de comando único para echo, que luego imprime las nuevas líneas directamente.Una nueva línea sin comillas es un espacio en blanco. Por lo tanto,
echo $1ofrece muchos argumentos de línea de comandos para echo, que los imprime uno tras otro separados por espacios.fuente