Julien Osman

Ingénieur développement logiciels. Docteur en télédétection.

Attentions aux crochets lorsque vous utilisez glob.glob


Cette semaine j'ai été confronté à un bug qui m'a occupé un petit moment. J'utilise un script qui prend en entrée le chemin vers un répertoire. Le script recherche certains fichiers dans le répertoire puis exécute un certain nombre d'opérations sur les fichiers trouvés. Ce script fonctionne très bien, et je l'ai utilisé de nombreuses fois sans soucis. Je le lance même couramment sur un cluster de calcul utilisant PBS pro, sans souci.

Jusqu'à cette semaine, où on m'a demandé de lancer mon script dans un job array. Un job array permet à PBS de lancer plusieurs fois le script sur plusieurs répertoires, en même temps. C'est très puissant et efficace, mais mon script ne fonctionnait plus : il ne trouvait aucun fichier dans le répertoire donné en entrée. Pourtant les fichiers étaient bien présents, je pouvais les voir en faisant un ls, et les droits étaient correctes.

Le répertoire donné en entrée est un répertoire temporaire créé par PBS dans lequel je viens déposer mes fichiers avant d'exécuter le script. Dans le cas d'un job classique, ce répertoire temporaire est de la forme /tmp/pbs.xxxxxx/ (avec xxxxxx l'id du job). Mais dans le cas d'un job array, chaque sous-job a un répertorie temporaire de la forme /tmp/pbs.xxxxxx[yy]/ (avec xxxxxx l'id du job array et yy l'id du sous-job). Et c'est la présence des crochets qui fait que mon script ne fonctionne plus (quelle idée de mettre des crochets dans des chemins aussi).

En effet, le script utilise la fonction glob.glob pour rechercher les fichiers dont il a besoin dans le répertoire d'entrée. Or, pour glob.glob, les crochets ont une signification bien particulière, et ils sont donc interprétés comme des caractères spéciaux. glob.glob me renvoie donc une liste vide. Pour éviter cela, il faut les échapper (en réalité, échapper le crochet ouvrant et suffisant). Pour échapper un caractère pour glob.glob, il suffit de l'encadrer avec ... des crochets ! Nous allons donc devoir remplacer tous les [ qui se trouvent dans notre chemin d'entrée, par [[]. En python c'est très simple, il suffit de faire :

my_path.replace('[', '[[]')

Et voila, l'erreur est corrigée, mon script fonctionne à présent dans des job array.

J'espère que cette astuce vous sera utile.