Copie batch sous Nautilus¶
Task spooler¶
J’ai toujours bien aimé le batch, ça doit doit venir de mes débuts sous IBM MVS/TSO/JCL dans les années 80. J’aime bien l’idée de soumettre les traitements, de les laisser s’exécuter tranquillement, quelque soit leur durée, puis de revenir voir le résultat un peu plus tard.
J’ai découvert assez récemment un outil tout à fait adapté à ce que je cherchais et très simple d’utilisation : task spooler. Le programme gère une file d’attente des jobs (job queue) et, par défaut, un seul s’exécute à la fois.
Sous Debian, le package existe et s’installe simplement:
sudo apt install task-spooler
Pour soumettre un job, il suffit de préfixer la commande par ts
(commande
prévue par l’auteur de task spooler) ou tsp
(sous Debian).
Exemple:
tsp rsync mon_fichier1 host:
tsp rsync mon_fichier2 host:
On a soumis 2 jobs de transfert de fichier qui vont s’exécuter l’un derrière l’autre.
On peut voir l’état des différents jobs avec la commande tsp
seule:
% tsp
ID State Output E-Level Times(r/u/s) Command [run=0/1]
0 finished /tmp/ts-out.q7UVkz -1 0.14/0.04/0.00 rsync mon_fichier1 host:
1 finished /tmp/ts-out.JcwIkK -1 0.17/0.04/0.00 rsync mon_fichier2 host:
Les fichiers Output permettent d’avoir la sortie de la commande tandis que la colonne E-level donne le code retour. Ici, on voit que le code -1 indique une erreur, ce qui est normal puisque ni les fichiers existent, ni le host.
Script Nautilus¶
Et si on utilisait task spooler pour séquencer les copies vers un périphérique lent (réseau, clé USB…) sous Nautilus ? Il suffit d’écrire un script.
Sous Debian/Ubuntu, il faut commencer par l’installation du package
nautilus-script-manager
.
Ensuite on peut écrire le script dans le répertoire
~/.local/share/nautilus/scripts
.
Je vais tout de suite donner le contenu du script et expliquer ensuite le contenu:
#!/bin/zsh
d=$(zenity --file-selection --directory)
if [ $? -eq 0 ] ; then
for f in ${(@f)NAUTILUS_SCRIPT_SELECTED_FILE_PATHS} ; do
tsp cp "$f" "$d"
done
fi
Attention, ce script ne fonctionne que sous zsh.
Comme souvent avec les scripts shell, le diable se cache dans les détails.
Ici, c’est dans le (@f)
devant la variable NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
que réside toute la subtilité.
Revenons au début.
Grâce à la commande zenity
, que j’ai découvert à cette occasion, on a une belle
fenètre pour cliquer sur le répertoire de destination.
Ensuite, Nautilus passe les fichiers sélectionnés dans la variable
NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
en séparant chaque nom de fichier
par un caractère \n
. Et comme les noms de fichiers peuvent contenir des
espaces ou tout autre caractère exotique, il faut traiter correctement
cette chaine.
Il y a peut-être d’autre solution mais, étant par ailleurs un habitué de Python, j’aime
bien les listes qui résolvent élégamment la question des arguments et des
délimiteurs. Or zsh possède cette notion via les arrays. Il serait intéressant
de pouvoir dire qu’on veut transformer une chaîne séparée par des \n
par un array
en splitant. Miracle (un fois qu’on a trouvé l’info) : c’est exactement ce que fait
(@f)
. Une fois qu’on a un array propre, il suffit de le parcourir et le reste
ne pose pas de difficulté particulière.