' est une erreur de répertoire ' lors de la tentative de transmission du nom de répertoire à la fonction

Dans mon script bash, jutilise find pour obtenir les noms de dossier par joker:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff ${i} done doStuff() { echo ${1} return ${1}"/hello"; } 

Le problème est que lorsque je fais cela, jobtiens lerreur suivante (disons que $ {i} correspond à « home / me / my_directory »):

line 111: "/home/me/my_directory": is a directory. 

(la ligne 111 est la ligne avec « doStuff « )

Jai essayé de faire ça, en vain:

for i in $(find ${directory} -mindepth 1 -type d -name ${wildcard}); do stuff=doStuff "${i}" done 

Apparemment, cest parce que le programme essaie dexécuter le répertoire, mais je le veux juste comme une chaîne que je peux manipuler.

Commentaires

  • Hmmm …. Daprès la page de manuel bash. … La commande intégrée return dans bash est utilisée pour renvoyer un code EXIT (entier) et non nimporte quel type de paramètre de chaîne.
  • Vous pouvez également essayer find "${directory}" -mindepth 1 -type d -name "${wildcard}" -print0 | xargs -0 doStuff
  • googleurs : une autre excellente source pour obtenir ce message derreur ge est //a wrong bash line comment au lieu de #a correct bash line comment

Réponse

Les citations et la substitution de commandes sont vos problèmes ici.

Le problème spécifique que vous « rencontrez » est que le shell essaie dexécuter une commande appelée /home/me/my_directory avec la variable denvironnement stuff=doStuff.
Ce que vous voulez vraiment (si je » m interprète correctement) est dexécuter doStuff avec la valeur $i comme argument, affectant la sortie à la variable stuff. Pour ce faire, vous devez encapsuler votre commande dans $(). Par exemple:

stuff="$(doStuff "$i")" 

Remarquez comment je mets également des guillemets autour de tout. Cela évite que le shell ne divise par mot les choses que vous ne voulez pas quil « scinde en mot » (il « transformera un seul argument de /foo/bar baz en /foo/bar et baz).

Le résultat de votre fonction est également ce qui est utilisé comme valeur de retour, et non return.

Comme vous devriez utiliser plus de guillemets, vous devriez également les ajouter à tout le reste. Voici une version complète de votre script:

doStuff() { echo "${1}" >&2 printf "%s/hello" "$1"; } IFS=$"\n" for i in $(find "${directory}" -mindepth 1 -type d -name "${wildcard}"); do stuff="$(doStuff "${i}")" done 

Vous devez mettre la définition de la fonction avant dessayer de lutiliser. Shell nest pas analysé comme les programmes compilés, où il parcourt le fichier plusieurs fois. Cest de haut en bas.
Jai également modifié doStuff pour envoyer le echo à STDERR où il sera affiché sur le terminal, puis printf envoie à STDOUT où il sera capturé dans la variable stuff.

Notez que cela posera toujours un problème si lun de vos répertoires contient une nouvelle ligne. Cependant, il sagit dune limitation du shell. Le seul caractère quun chemin de fichier ne peut pas contient est un caractère NULL (\0). Cependant, bash et dautres shells ne peuvent pas stocker un caractère NULL dans une chaîne (pas tous, mais beaucoup. Je sais que zsh peut), donc vous pouvez  » t lutiliser comme délimiteur.

Commentaires

  • Je voulais juste ajouter que si vous avez de lespace avant / après =, ça gâche. par exemple. MY_VAR = ' / some / path ' est valide mais MY_VAR = ' / some / chemin ' ou MY_VAR = ' / some / path ' nest pas

Réponse

Cest un bon effort mais cela montre que vous essayez décrire bash comme sil sagissait dun langage de programmation, alors quil sagit en fait dun simple langage de script. Le problème avec votre construction stuff=doStuff arg est que bash ne veut pas dire ce que vous pensez que cela signifie. Pour bash, stuff=doStuff est une affectation de variable et arg est une commande. Je vous suggère de lire les deux liens suivants:

Une version fonctionnelle de quelque chose de similaire à ce que vous avez serait

doStuff () { echo "$1/hello" } stuff=$(doStuff "$i") 

Réponse

La ligne donnant lerreur ne fait pas ce que vous pensez quelle fait:

Il définit dabord la variable denvironnement stuff sur la chaîne « doStuff », puis essaie dexécuter $ {i} en tant que commande. Et puisque $ {i} est un répertoire, cela échoue avec le message derreur donné.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *