Attentions aux crochets lorsque vous utilisez glob.glob
S'il y a des crochets dans le chemin que vous donnez à glob.glob, vous risquez d'obtenir une liste vide en sortie. Voici une solution.
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.