En utilisant la sortie de ls
pour obtenir les noms de fichiers est une mauvaise idée . Cela peut conduire à des dysfonctionnements, voire à des scripts dangereux. En effet, un nom de fichier peut contenir n'importe quel caractère sauf /
et le null
caractère, et ls
n'utilise aucun de ces caractères comme délimiteurs. Par conséquent, si un nom de fichier comporte un espace ou un saut de ligne, vous pouvez utiliser la fonction se obtenir des résultats inattendus.
Il y a deux très bonnes façons d'itérer sur les fichiers. Ici, j'ai utilisé simplement echo
pour démontrer qu'il faut faire quelque chose avec le nom du fichier ; vous pouvez cependant utiliser n'importe quoi.
La première consiste à utiliser les fonctionnalités natives de globbing du Shell.
for dir in */; do
echo "$dir"
done
Le Shell s'étend */
en arguments distincts que le for
même s'il y a un espace, une nouvelle ligne ou tout autre caractère étrange dans le nom du fichier, for
verra chaque nom complet comme une unité atomique ; il n'analyse pas la liste de quelque façon que ce soit.
Si vous voulez aller récursivement dans les sous-répertoires, alors cela ne fonctionnera pas à moins que votre Shell ait des fonctionnalités de globbing étendues (telles que bash
's globstar
. Si votre Shell n'a pas ces fonctionnalités, ou si vous voulez vous assurer que votre Shell fonctionnera sur une variété de systèmes, alors l'option suivante est d'utiliser find
.
find . -type d -exec echo '{}' \;
Ici, le find
appelle la commande echo
et lui passe en argument le nom du fichier. Il le fait une fois pour chaque fichier qu'il trouve. Comme dans l'exemple précédent, il n'y a pas d'analyse syntaxique d'une liste de noms de fichiers ; au lieu de cela, un nom de fichier est envoyé complètement comme argument.
La syntaxe du -exec
L'argument a l'air un peu bizarre. find
prend le premier argument après -exec
et le traite comme le programme à exécuter, et chaque argument suivant, il le prend comme un argument à passer à ce programme. Il y a deux arguments spéciaux que -exec
a besoin de voir. Le premier est {}
; cet argument est remplacé par un nom de fichier que les parties précédentes de la commande find
génère. Le second est ;
qui permet find
savoir que c'est la fin de la liste des arguments à passer au programme ; find
a besoin de cela car on peut continuer avec plus d'arguments destinés find
et non destiné au programme exécuté. La raison pour laquelle le \
est que le Shell traite également ;
spécialement - il représente la fin d'une commande, donc nous devons l'échapper pour que le Shell le donne comme argument à find
plutôt que de le consommer pour lui-même ; une autre façon d'obtenir que le Shell ne le traite pas spécialement est de le mettre entre guillemets : ';'
fonctionne tout aussi bien que \;
à cette fin.