for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
Je comprends pourquoi 1 diffère de 2. Mais pourquoi 3 donne-t-il une sortie différente de 2? Veuillez également expliquer la sortie. Comment fonctionnent les devis sur les nouvelles lignes?
Réponses:
Une variable sans guillemets (comme dans
$var
) ou une substitution de commande (comme dans$(cmd)
ou`cmd`
) est l' opérateur split + glob dans des shells de type Bourne.Autrement dit, leur contenu est divisé en fonction de la valeur actuelle de la
$IFS
variable spéciale (qui contient par défaut l'espace, la tabulation et les caractères de nouvelle ligne)Et puis chaque mot résultant de ce fractionnement est soumis à la génération de nom de fichier (également connu sous le nom de globbing ou expansion de nom de fichier ), c'est-à-dire qu'ils sont considérés comme des modèles et sont développés dans la liste des fichiers qui correspondent à ce modèle.
Donc, dans
for i in $(xrandr)
,$(xrandr)
parce qu'il n'est pas entre guillemets, est divisé en séquences d'espaces, de tabulations et de caractères de nouvelle ligne. Et chaque mot résultant de ce fractionnement est vérifié pour les noms de fichiers correspondants (ou laissé tel quel s'il ne correspond à aucun fichier), et lesfor
boucle tous.Dans
for i in "$(xrandr)"
, nous n'utilisons pas l'opérateur split + glob car la substitution de commandes est citée, donc il y a un passage dans la boucle sur une valeur: la sortie dexrandr
(sans les caractères de fin de ligne qui commandent les bandes de substitution ).Cependant, dans
echo $i
,$i
est à nouveau sans guillemets, donc à nouveau le contenu de$i
est divisé et soumis à la génération du nom de fichier et ceux-ci sont passés comme arguments séparés à laecho
commande (etecho
sort ses arguments séparés par des espaces).Donc, la leçon apprise:
$IFS
conséquence et / ou activez ou désactivez la génération de noms de fichiers si nécessaire (set -f
,set +f
).En règle générale, dans votre exemple ci-dessus, si vous souhaitez parcourir la liste de mots séparés par des blancs dans la sortie de
xrandr
, vous devez:$IFS
à sa valeur par défaut (ou la désactiver) pour diviser les blancsset -f
option pour désactiver la génération de nom de fichier, sauf si vous êtes sûr dexrandr
ne jamais générer de caractères*
ou?
ou[
(qui sont des caractères génériques utilisés dans les modèles de génération de nom de fichier)Et puis utilisez uniquement l'opérateur split + glob (ne laissez que la substitution de commandes ou l'expansion de variables non citée) dans la
in
partie de lafor
boucle:Si vous souhaitez parcourir les lignes (non vides) de la
xrandr
sortie, vous devez définir$IFS
le caractère de nouvelle ligne:la source
Une nouvelle ligne citée est une nouvelle ligne.
echo "$1"
Donne donc un seul argument de ligne de commande à echo, qui imprime ensuite directement les retours à la ligne.Une nouvelle ligne sans guillemets est un espace.
echo $1
Donne donc de nombreux arguments de ligne de commande à echo, qui les affiche l'un après l'autre séparés par des espaces.la source