L’utilitaire de correctifs Linux permet d’appliquer des modifications d’un ensemble de fichiers à un autre, de manière rapide et sécurisée. Découvrez comment utiliser `patch` simplement.
Les outils `patch` et `diff`
Imaginez que vous possédez un fichier texte et que vous recevez une version modifiée de celui-ci. Comment transférer rapidement les changements de la version modifiée vers votre fichier original? C’est là que les commandes `patch` et `diff` entrent en jeu. Elles sont disponibles sous Linux, ainsi que sur d’autres systèmes d’exploitation de type Unix, comme macOS.
La commande `diff` analyse deux versions distinctes d’un fichier et identifie les différences entre elles. Ces différences peuvent être enregistrées dans un fichier, appelé fichier de correctif.
La commande `patch` lit un fichier de correctif et utilise son contenu comme un ensemble d’instructions. En suivant ces instructions, les modifications de la version mise à jour sont reproduites dans le fichier original.
Imaginez maintenant que ce processus s’applique à tout un répertoire de fichiers texte, simultanément. C’est la puissance de `patch`.
Parfois, vous ne recevez pas les fichiers modifiés, mais seulement le fichier de correctif. Pourquoi envoyer des dizaines de fichiers quand un seul peut être transmis ou publié pour un téléchargement aisé ?
Comment appliquer ce fichier de correctif pour mettre à jour vos fichiers? C’est une question légitime à laquelle nous répondrons dans cet article.
La commande `patch` est souvent employée par les développeurs de logiciels, mais elle fonctionne aussi bien avec n’importe quel ensemble de fichiers texte, qu’il s’agisse de code source ou non.
Notre scénario d’exemple
Dans ce cas, nous nous trouvons dans un répertoire nommé `work`, qui contient deux autres répertoires: `working` et `latest`. Le répertoire `working` contient un ensemble de fichiers de code source. Le répertoire `latest` contient la version la plus récente de ces fichiers, dont certains ont été modifiés.
Pour être précis, le répertoire `working` est une copie de la version actuelle des fichiers texte. Ce n’est pas l’unique copie.
Identifier les différences entre deux versions d’un fichier
La commande `diff` repère les différences entre deux fichiers. Son comportement par défaut est d’afficher les lignes modifiées dans la fenêtre du terminal.
Un fichier nommé `slang.c` est utilisé. Nous allons comparer sa version du répertoire `working` avec celle du répertoire `latest`.
L’option `-u` (unifiée) demande à `diff` d’inclure également les lignes de texte non modifiées avant et après chaque section modifiée. Ces lignes sont appelées lignes de contexte. Elles aident la commande `patch` à identifier précisément où une modification doit être apportée dans le fichier d’origine.
Nous spécifions les noms des fichiers afin que `diff` sache quels fichiers comparer. Le fichier original est indiqué en premier, suivi du fichier modifié. Voici la commande que nous exécutons pour `diff` :
diff -u working/slang.c latest/slang.c
`diff` produit une liste montrant les différences entre les fichiers. S’ils étaient identiques, aucune sortie ne serait affichée. La présence d’une telle sortie confirme l’existence de différences entre les deux versions du fichier et la nécessité de corriger le fichier original.
Créer un fichier de correctifs
Pour enregistrer ces différences dans un fichier de correctif, utilisez la commande suivante. C’est la même commande que précédemment, sauf que la sortie de `diff` est redirigée vers un fichier appelé `slang.patch`.
diff -u working/slang.c latest/slang.c > slang.patch
Le nom du fichier de correctif est arbitraire. Vous pouvez le nommer comme vous le souhaitez. L’extension «.patch» est une bonne pratique, car elle indique clairement le type de fichier.
Pour que `patch` utilise le fichier de correctif et modifie le fichier `working/slang.c`, employez la commande suivante. L’option `-u` (unifiée) informe `patch` que le fichier de correctif contient des lignes de contexte unifiées. Autrement dit, nous avons utilisé l’option `-u` avec `diff`, nous l’utilisons donc avec `patch`.
patch -u working/slang.c -i slang.patch
Si tout se passe bien, une seule ligne s’affiche indiquant que le correctif a modifié le fichier.
Sauvegarder le fichier original
Nous pouvons demander à `patch` de créer une copie de sauvegarde des fichiers avant qu’ils ne soient modifiés, en utilisant l’option `-b` (sauvegarde). L’option `-i` (entrée) indique à `patch` le nom du fichier de correctif à utiliser:
patch -u -b working/slang.c -i slang.patch
Le fichier est corrigé comme précédemment, sans différence visible dans la sortie. Cependant, si vous examinez le dossier `working`, vous verrez qu’un fichier nommé `slang.c.orig` a été créé. La date et l’heure des fichiers indiquent que `slang.c.orig` est le fichier original et que `slang.c` est un nouveau fichier créé par `patch`.
Utiliser `diff` avec des répertoires
Nous pouvons utiliser `diff` pour créer un fichier de correctif contenant toutes les différences entre les fichiers de deux répertoires. Ensuite, nous pouvons employer ce fichier de correctif avec `patch` pour appliquer ces changements aux fichiers du dossier `working` en une seule commande.
Les options que nous allons utiliser avec `diff` sont l’option `-u` (contexte unifié) employée précédemment, l’option `-r` (récursive) pour que `diff` explore tous les sous-répertoires, et l’option `-N` (nouveau fichier).
L’option `-N` indique à `diff` comment traiter les fichiers du répertoire `latest` qui ne sont pas présents dans le répertoire `working`. Cela force `diff` à inclure des instructions dans le fichier de correctif afin que `patch` crée les fichiers présents dans `latest` mais absents de `working`.
Vous pouvez combiner les options pour n’utiliser qu’un seul tiret (-).
Notez que nous indiquons seulement les noms des répertoires, sans spécifier à `diff` de rechercher des fichiers précis:
diff -ruN working/ latest/ > slang.patch
Un coup d’œil à l’intérieur du fichier de correctif
Examinons le contenu du fichier de correctif. Nous allons utiliser la commande `less` pour visualiser son contenu.
Le début du fichier présente les différences entre les deux versions de `slang.c`.
En faisant défiler le fichier de correctif, nous constatons qu’il décrit ensuite les changements dans un autre fichier nommé `structs.h`. Cela confirme que le fichier de correctif contient bien les différences entre les différentes versions de plusieurs fichiers.
Réfléchir avant d’agir
Appliquer des correctifs à un grand ensemble de fichiers peut être déroutant. Par conséquent, nous allons utiliser l’option `–dry-run` pour vérifier que tout se passe bien avant de réellement effectuer les changements.
L’option `–dry-run` indique à `patch` d’effectuer toutes les actions préparatoires, à l’exception de la modification effective des fichiers. `patch` effectue toutes ses vérifications préliminaires sur les fichiers et signale tout problème. Dans tous les cas, aucun fichier n’est modifié.
Si aucun problème n’est signalé, nous pouvons répéter la commande sans l’option `–dry-run` et mettre à jour nos fichiers en toute sécurité.
L’option `-d` (répertoire) indique à `patch` dans quel répertoire travailler.
Notez que nous n’utilisons pas l’option `-i` (entrée) pour spécifier à `patch` le fichier de correctif contenant les instructions de `diff`. Au lieu de cela, nous redirigeons le fichier de correctif vers `patch` avec `<`.
patch --dry-run -ruN -d working < slang.patch
Sur l’ensemble du répertoire, `diff` a trouvé deux fichiers à corriger. Les instructions concernant les modifications de ces deux fichiers ont été vérifiées par `patch`, et aucun problème n’a été détecté.
Les vérifications préliminaires sont correctes; nous sommes prêts à démarrer.
Appliquer les correctifs à un répertoire
Pour appliquer réellement les correctifs aux fichiers, nous utilisons la commande précédente sans l’option `–dry-run`.
patch -ruN -d working < slang.patch
Cette fois, chaque ligne de sortie ne commence pas par «vérification», mais par «correction».
Aucun problème n’est signalé. Nous pouvons compiler notre code source et utiliser la dernière version du logiciel.
Gérez vos différences
C’est de loin la méthode la plus simple et la plus sûre d’utiliser `patch`. Copiez vos fichiers cibles dans un répertoire, puis appliquez les correctifs à ce répertoire. Recopiez-les une fois que vous êtes certain que le processus de mise à jour s’est déroulé sans erreurs.