Au retour, j’ai écrit un script shell qui exécute automatiquement un script python sur tout fichier c ++ qu’il peut trouver dans un répertoire spécifié. Je l’ai testé, ça a bien fonctionné, je l’ai enregistré et j’ai oublié; Le problème est que je suis revenu pour l’utiliser et rencontré un problème (il s’avère que je ne l’ai pas assez testé hein?).
Quoi qu’il en soit, les chemins de répertoire source que je testais auparavant n’avaient aucun espace, par exemple
/somedirectory/subfolder/src/
Mais quand j’essaie d’exécuter le script en utilisant un chemin avec des espaces, par exemple
/Documents\ and\ Settings/subfolder/src/
Ça ne marche pas
J’ai trouvé où est le problème, mais je ne sais pas comment le réparer. Voici le code à l’origine du problème:
names=( $(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$"))
L’expression régulière fonctionne avec des chemins sans espaces. Je ne suis donc pas sûr qu’il y ait un problème avec l’expression régulière ou si la commande “find” s’arrête lorsqu’elle rencontre un espace.
Quelqu’un peut-il aider?
find
ne s’arrête pas quand il frappe des fichiers avec des espaces dans leurs noms. Le problème se produit lorsque vous essayez de les stocker en tant qu’éléments dans un tableau.
Remplacez IFS par le caractère de nouvelle ligne (par défaut, il s’agit d’espace):
#change IFS OLDIFS=$IFS IFS=$'\n' #run find names=($(find . -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$")) #restore IFS IFS=$OLDIFS #test out the array echo "size: ${#names[@]}" for i in "${names[@]}" do echo "$i" done
Le modèle d’utilisation canonique est le suivant:
find subfolder/ -type f -name '*.cpp' -print0 | xargs -0rn1 myscript.py
Cela a toutes les cloches et les sifflets, vous pouvez probablement faire sans -type f
et peut-être certains des drapeaux xargs
vous pouvez utiliser read
while read -r file; do names+=("$file") done < <(find "${SOURCE_ROOT_DIRECTORY}" -regex "[A-Za-z0-9]*.*\(cpp\|h\|cc\)$")
un petit test
$ mkdir -p /tmp/test && cd $_ $ touch foo bar "ab cd" $ ls ab cd bar foo $ while read -r file; do names+=("$file"); done < <(find /tmp/test -type f); $ echo ${#names[@]} 3 $ for file in "${names[@]}"; do echo "$file"; done; /tmp/test/ab cd /tmp/test/bar /tmp/test/foo $ unset names file