dpkg possède un système de diversion qui permet de modifier un fichier normalement géré par un paquet.
Pour être plus clair, imaginons un fichier [mono]/usr/bin/myapp[/mono] qui est installé par le paquet [mono]myapp[/mono]. Je souhaite remplacer se binaire pour utiliser un wrapper. Par exemple¹ :
#!/bin/sh
export MY_VAR_ENV=0
exec /usr/bin/myapp
Si je renomme directement [mono]/usr/bin/myapp[/mono] en [mono]/usr/bin/myapp.real[/mono] et que mon script [mono]/usr/bin/myapp[/mono] :
#!/bin/sh
export MY_VAR_ENV=0
exec /usr/bin/myapp.real # attention à ne pas rappeller votre wrapper ici…
À la prochaine mise à jour du paquet myapp, je perds toute ma conf…
La diversion sert à ça, on va dire à dpkg que s’il souhaite créer ou mettre à jour le fichier [mono]/usr/bin/myapp[/mono], il devra plutôt le mettre à [mono]/usr/bin/myapp.real[/mono]. C’est cool, non ? Pour faire ça il vous suffit d’une commande :
Pour supprimer la règle, on fait :
Maintenant prenons un cas pratique : le bug 733757 (vous pouvez trouver des explications en français sur linuxfr).
La solution consiste à modifier le fichier [mono]/usr/share/X11/xkb/symbols/fr[/mono].
Pour ça on commence par regarder le paquet qui a installé le fichier (bon là vu qu’on voit un rapport de bug, on sait déjà, mais en vrai j’ai découvert ce problème par le journal linuxfr) :
On voit que c’est [mono]xkb-data[/mono], maintenant on regarde si c’est considéré comme un fichier de configuration. En effet s’il s’agit d’un fichier de configuration, le mieux c’est de le modifier directement et notre gestionnaire de paquet préféré, nous avertira quand il voudra le remplacer (voir l’article de Raphael Hertzog sur le sujet) :
# grep '/usr/share/X11/xkb/symbols/fr' /var/lib/dpkg/info/xkb-data.conffiles
grep: /var/lib/dpkg/info/xkb-data.conffiles: Aucun fichier ou dossier de ce type
On va donc devoir utiliser une diversion pour ça :
puis on crée notre propre version du fichier :
Et c’est bon ! (je me suis abonné à ce bug pour savoir quand retirer ma diversion)
Je me dois par contre de faire une mise en garde, multiplier les diversions rend la maintenance du système bien plus complexe (vous interférez dans le travail des mainteneurs de Debian), il faut utiliser ça avec parcimonie (vraiment) et toujours chercher d’autres solutions. C’est une solution de dernier recours. Vous pouvez lister les détournements existants avec la commande :
[1] : l’exemple n’est pas très pertinent il vaut probablement mieux créer la variable dans [mono]/etc/environment[/mono]