Au début d'un script shell bash se trouve la ligne suivante:
IFS=$'\n'
Quelle est la signification de cette collection de symboles?
Au début d'un script shell bash se trouve la ligne suivante:
IFS=$'\n'
Quelle est la signification de cette collection de symboles?
Réponses:
IFSest synonyme de "séparateur de champ interne". Le shell l’utilise pour déterminer comment scinder le mot, c’est-à-dire reconnaître les limites de mot.
Essayez ceci dans un shell comme bash (d'autres shells peuvent gérer cela différemment, par exemple zsh):
mystring="foo:bar baz rab"
for word in $mystring; do
echo "Word: $word"
done
La valeur par défaut pour se IFScompose de caractères d'espacement (pour être précis: espace, tabulation et nouvelle ligne). Chaque caractère peut être une limite de mot. Donc, avec la valeur par défaut de IFS, la boucle ci-dessus affichera:
Word: foo:bar
Word: baz
Word: rab
En d'autres termes, le shell pense que les espaces sont une limite de mots.
Maintenant, essayez de régler IFS=:avant d’exécuter la boucle. Cette fois, le résultat est:
Word: foo
Word: bar baz rab
Le shell se divise également mystringen mots - mais à présent, il ne traite que les deux points comme la limite de mot.
Le premier caractère de IFSest spécial: il est utilisé pour délimiter des mots dans la sortie lorsque vous utilisez la $*variable spéciale (exemple tiré du Guide de script de Bash avancé , où vous pouvez également trouver plus d'informations sur des variables spéciales comme celle-ci):
$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z
Comparer aux:
$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z
Notez que dans les deux exemples, la coquille continue de traiter tous les personnages :, -et ;que les limites de mots. La seule chose qui change est le comportement de $*.
Une autre chose importante à savoir concerne le traitement de ce que l'on appelle les "espaces blancs IFS" . Fondamentalement, dès que IFSles caractères d'espacement sont inclus, les espaces de début et de fin sont supprimés de la chaîne à scinder avant d'être traités et une séquence de caractères d'espacement consécutifs délimite également les champs. Toutefois, cela ne s'applique qu'aux caractères d'espacement réellement présents dans IFS.
Par exemple, regardons la chaîne "a:b:: c d "(espace de fin et deux espaces entre cet d).
IFS=:elle serait divisée en quatre champs: "a", "b", ""(chaîne vide) et " c d "(encore une fois, deux espaces entre cet d). Notez les espaces de début et de fin dans le dernier champ.IFS=' :', il serait divisé en cinq domaines: "a", "b", ""(chaîne vide), "c"et "d". Aucun espace de début et de fin nulle part.Notez que plusieurs caractères d'espacement consécutifs délimitent deux champs dans le deuxième exemple, tandis que plusieurs points consécutifs ne le sont pas (car ils ne sont pas des caractères d'espacement).
En ce qui concerne IFS=$'\n', qui est une ksh93syntaxe également pris en charge par bash, zsh, mkshet FreeBSD sh(avec des variations entre les coquilles). Citant la page de manuel bash:
Les mots de la forme $ 'chaîne' sont traités spécialement. Le mot se développe en "chaîne", avec les caractères d'échappement avec une barre oblique inversée remplacés comme spécifié par la norme ANSI C.
\nest la séquence d'échappement pour une nouvelle ligne, IFSfinit par être défini sur un seul caractère de nouvelle ligne.
bashguide de script, ou peu importe. Dans l’ensemble, l’information disponible sur des liens comme celui-ci manque de façon importante. Quoi qu’il en soit, il manque donc deux points cruciaux concernant la division du shell - le globbing et les espaces blancs IFS.
unset IFSun shell se comporte de manière très différente de IFS=. Le premier octet dans IFS est également spécial "${named_array[*]}"- mais cela n’a aucune importance lorsque l’extension n’est pas citée ..
$IFSest l'une des deux choses principales exécutées lors de l'expansion d'une variable non citée dans le contexte d'une liste (c'est la splitpartie de l' split+globopérateur). L'autre est globbing. Lorsque vous utilisez le fractionnement du travail, vous devez généralement émettre set -fpour désactiver la globpièce.
$IFSest également utilisé par la readcommande intégrée
Dans les guillemets simples en dollars, certains caractères sont évalués spécialement. Par exemple, \nest traduit en nouvelle ligne.
Donc, cette ligne particulière affecte newline à la variable IFS. IFS, à son tour, est une variable spéciale dans bash: séparateur de champ interne. Comme man bashdit, il
est utilisé pour séparer les mots après le développement et pour séparer les lignes en mots avec la
readcommande interne. La valeur par défaut est<space><tab><newline>.
dollared single quotesce qui est différent des simples guillemets simples.
Pour faire court, IFS=$'\n'attribuez newline \nà variable IFS.
$'string'construct est un mécanisme de citation qui décode les séquences d'échappement de type ANSI C. Cette syntaxe provient ksh93et est portable shell moderne comme bash, zsh, pdksh, busybox sh.
Cette syntaxe n'est pas définie par POSIX, mais a été acceptée pour le problème 7 de SUS .
J'ai préféré expliquer $IFSpar l'exemple:
supposons que vous vouliez utiliser cp, mv ou un autre processus de traitement de fichier, IFS est vide par défaut, lorsque vos fichiers ont un caractère méta ou un espace tel que:
Linux Administration.pdfou Free Software Fundation.ogg, bien sûr, vous aurez un problème, car: Linux considère un séparer param et Administartion considèrent un séparateur séparé.Alors bash a built-in variable, ensuite vous pouvez initialiser à IFS==$(echo -en "\n\b"), puis bash ignorer tout caractère méta et l'espace entre le nom de fichier, Par exemple:
#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS