Il y a presque deux ans, j'ai rippé la quasi-totalité de mes CDs musicaux pour les stocker, en FLAC, sur un gros disque dur externe. C'est bien, mais pour des raisons de transportabilité, j'ai envie de les réencoder en Ogg Vorbis. Mais vu le volume de ma discothèque fait que je n'ai pas envie de me taper cette tâche à la main.
Alors j'ai entrepris de m'écrire un script pour faire le boulot à ma place. En Perl, parce que c'est plus souple et plus structuré que le Shell, et qu'un certain nombre des opérations nécessitent les expressions régulières donc... ai-je besoin de continuer ? Et avant qu'on me dise qu'il y a déjà des applis pour ça, je réponds que je m'en doute, mais que ça m'amuse.
Le principe général de mon script exploite le fait que, lorsque j'ai rippé mes CDs, au moyen de l'appli abcde (que je recommande à tous les linuxien-nes) , j'ai fait générer par ladite appli des fichiers M3U indiquant chacun le chemin des fichiers d'un album, chaque album étant dans son propre sous-répertoire.
Je fournis à mon script deux arguments : le répertoire source, où il va chercher des fichiers M3U à exploiter, et le répertoire cible, préexistant, où seront envoyés les albums réencodés, chacun dans leur sous-répertoire, ainsi que les M3U correspondants que je génère dans la foulée. À cela s'ajoute un paramètre -d (pour délai, ou delay si vous préfèrez), numérique, exprimant en minutes la durée après laquelle mon script ne devra plus essayer de réencoder de nouvel album. Ceci parce que, sur ma machine, après quelques essais, il semble que le réencodage total de ma discothèque prendrait plusieurs dizaines d'heures. Autant y aller par morceaux. Et du coup mon script crée, dans le répertoire source, un fichier listant les M3U déjà traités.
Pour des raisons d'efficacité, j'ai décidé de passer par un répertoire temporaire pour réencoder mes fichiers FLAC, puis de déplacer le tout vers la cible. En effet, des mémoires de masse externes étant impliquées, avec les limitations que cela implique, je préfère que le gros du travail soit effectué sur le disque interne, puis que l'envoi du résultat soit fait en bloc. J'ai même été jusqu'à le faire faire par un processus fils au moyen d'un fork, histoire que le réencodage de l'album suivant commence le plus vite possible.
Soit dit en passant, j'ai des doutes sur l'efficacité de ces choix. Si quelqu'un a des remarques éclairées à faire à ce sujet, je suis preneur.
Mais j'en viens (enfin) au fait. Je passe donc par un répertoire temporaire, dont je dois envoyer le contenu à la cible prévue. Or, ladite cible n'est pas nécessairement dans le même système de fichier que le répertoire temporaire (dans mon cas, c'est même certain). L'usage de la commande rename est donc exclu, vu qu'elle ne marche qu'au sein d'un même système de fichier. Comme je souhaite éviter de passer par un appel système "mv -r", je farfouille sur le web et dans le CPAN. Je trouve le module File::Copy, et je commence à réfléchir à comment l'utiliser. J'en suis à envisager d'utiliser File::Find conjointement, puis je reprends mes esprits et je cherche un peu mieux. Et je trouve ce qu'il me faut : File::Copy::Recursive !
J'explore, et je trouve ce qui semble être LA fonction qu'il me faut : rmove_glob, qui fonctionne en principe comme un mv -r avec une expression glob en premier argument.
Et là, comme ils disent sur M6, c'est le drame. Je ne trouve pas moyen de l'utiliser. J'ai d'abord essayé avec use File::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove); comme il est indiqué sur la page CPAN, mais quand j'essaie d'utiliser rmove_glob, j'obtiens le message Undefined subroutine &main::rmove_glob une fois que le script atteint le point où j'appelle rmove_glob.
Qu'à cela ne tienne, j'essaie en ajoutant rmove_glob à la liste des méthodes appelées. Là, mon script foire à la compilation, avec pour message "rmove_glob" is not exported by the File::Copy::Recursive module.
Qu'à cela ne tienne, je vire rmove_glob de la liste des imports, et j'utilise File::Copy::Recursive->rmove_glob
Le resultat est un Rien spectaculaire. Je ne reçois aucun message d'erreur. Mais il ne se passe rien. Mes fichiers n'ont pas bougé.
Et il se passe la même chose si je vire la liste des imports.
Du coup, je suis bloqué. La méthode rmove_glob du module File::Copy::Recursive est-elle utilisable, et si oui, comment ?
Partager