Utiliser diff et patch sous Linux
Table des matières
Les commandes diff et patch sont des outils utilisés dans les systèmes Linux pour comparer et appliquer des différences entre des fichiers.
La commande diff est utilisée pour comparer le contenu de deux fichiers et afficher les différences ligne par ligne.
On pourra stocker ces différences dans un fichier via une redirection (par exemple maj.patch)
On pourra ensuite appliquer la mise à jour d'une copie de ce même fichier source grâce à la commande patch.
Cela permet :
- d'éviter de retransférer le fichier complet
- de patcher plusieurs fichiers dans plusieurs dossiers
- d'appliquer une modification rapidement
- de pouvoir annuler la modification faite rapidement
On retrouvera le type d'affichage produit par la commande diff dans des outils de gestion de version tels que git.
La commande diff est essentiellement utilisée pour comparer le contenu de deux fichiers et afficher les différences ligne par ligne.
Si la commande n'est pas disponible, on installera le paquet diffutils.
Voici la syntaxe :
Afin de voir cela avec un exemple, on va créer 2 fichiers :
livre.txt :
livre-correction.txt en corrigeant la faute ligne 2 :
Sans options, la commande diff suivante :
Va renvoyer :
La syntaxe signifie :
Il existe des options utiles :
Voici une sortie plus familière avec l'option -u :
La sortie générée est
Si vous n'êtes pas familier avec cette sortie, voici la signification :
Evidemment, on pourra générer un fichier de patch ainsi avec une simple redirection :
Si on a plusieurs fichiers à corriger, on pourra ajouter à la suite les corrections sans soucis.
Afin que patch sache quels fichiers traités, l'option -u est obligatoire à chaque invocation de diff, afin d'inclure le nom des fichiers à patcher :
La commande patch, quant à elle, est utilisée pour appliquer des différences générées par la commande diff à un fichier source. Elle permet d'appliquer des correctifs ou des modifications à un fichier de manière automatique.
Si la commande n'est pas disponible, on installera le paquet patch.
Voici la syntaxe :
Il existe des options utiles :
Si nous reprenons notre exemple, on imagine que notre destinataire n'a que le fichier (à patcher) livre.txt. On va simplement lui envoyer le fichier maj.patch
On appliquera la modification comme ceci :
Le système indique que l'opération s'est bien déroulée :
Pour annuler un patch, avec l'option -R on utilisera la commande comme ceci :
Dans le cas où plusieurs fichiers ont été patchés, on utilisera la syntaxe sans spécifier le nom des fichiers à patcher et on aura le retour suivant :
Il existe une option intéressante dans le cas où l'arborescence diffère, c'est l'option -pN où :
Je prends un exemple où on a un serveur de test où l'arborescence est :
Et le serveur de prod est :
Si le patch a été fait dans le dossier parent de "test", on a les chemins de fichiers sous cette forme :
Or, cette arborescence sur le serveur de production n'existe pas, elle est différente.
On ne pourra pas patcher car les fichiers ne se trouvent pas dans le dossier "test".
On placera dans ce cas le patch dans le dossier "prod" directement, et on demandera à patch de supprimer un niveau de répertoire :
Introduction
Les commandes diff et patch sont des outils utilisés dans les systèmes Linux pour comparer et appliquer des différences entre des fichiers.
La commande diff est utilisée pour comparer le contenu de deux fichiers et afficher les différences ligne par ligne.
On pourra stocker ces différences dans un fichier via une redirection (par exemple maj.patch)
On pourra ensuite appliquer la mise à jour d'une copie de ce même fichier source grâce à la commande patch.
Cela permet :
- d'éviter de retransférer le fichier complet
- de patcher plusieurs fichiers dans plusieurs dossiers
- d'appliquer une modification rapidement
- de pouvoir annuler la modification faite rapidement
On retrouvera le type d'affichage produit par la commande diff dans des outils de gestion de version tels que git.
La commande diff
La commande diff est essentiellement utilisée pour comparer le contenu de deux fichiers et afficher les différences ligne par ligne.
Si la commande n'est pas disponible, on installera le paquet diffutils.
Voici la syntaxe :
Code BASH :
diff [options] fichier1 fichier2
Afin de voir cela avec un exemple, on va créer 2 fichiers :
livre.txt :
Code TEXT :
Il était un petiot navire Il était un petit navire qui n'avait ja-ja jamais navigué
livre-correction.txt en corrigeant la faute ligne 2 :
Code TEXT :
Il était un petit navire Il était un petit navire qui n'avait ja-ja jamais navigué
Sans options, la commande diff suivante :
Code BASH :
diff livre.txt livre-correction.txt
Va renvoyer :
Code TEXT :
2c2 < petiot navire --- > petit navire
La syntaxe signifie :
- 2c2 : indique que la différence se trouve à la ligne 2 dans le premier fichier et à la ligne 2 dans le deuxième fichier.
- < petiot navire : ligne présente uniquement dans le premier fichier et contient le texte "petiot navire".
- --- ligne de séparation des deux blocs de différences.
- > petit navire : ligne présente uniquement dans le deuxième fichier et contient le texte "petit navire".
Il existe des options utiles :
- -u : Affiche au format unifié
- -r : Compare 2 répertoires de façon récursive
- -q : Indique si les fichiers sont différents (sans afficher les différences)
- -s : Indique clairement que les fichiers sont identiques (sinon, aucun résultat n'est produit)
Voici une sortie plus familière avec l'option -u :
Code BASH :
diff -u livre.txt livre-correction.txt
La sortie générée est
Code TEXT :
--- livre.txt 2024-02-13 18:04:50.213456100 +0100 +++ livre-correction.txt 2024-02-13 18:05:03.053789097 +0100 @@ -1,5 +1,5 @@ Il était un -petiot navire +petit navire Il était un petit navire qui n'avait ja-ja jamais navigué
Si vous n'êtes pas familier avec cette sortie, voici la signification :
- --- livre.txt : Nom du premier fichier
- +++ livre-correction.txt : Nom du deuxième fichier
- @@ -1,5 +1,5 @@ : Partie du fichier où les changements ont été apportés. Ici, les modifications ont commencé à la ligne 1 et se sont étendues sur 5 lignes dans chaque fichier.
- -petiot navire : Ligne qui a été supprimée dans le premier fichier.
- +petit navire : Ligne qui a été ajoutée dans le deuxième fichier.
- Le reste du texte représente le contenu des fichiers à partir de la ligne où les changements ont été détectés.
Evidemment, on pourra générer un fichier de patch ainsi avec une simple redirection :
Code BASH :
diff -u livre.txt livre-correction.txt > maj.patch
Si on a plusieurs fichiers à corriger, on pourra ajouter à la suite les corrections sans soucis.
Afin que patch sache quels fichiers traités, l'option -u est obligatoire à chaque invocation de diff, afin d'inclure le nom des fichiers à patcher :
Code BASH :
diff -u autre_fichier.txt autre_fichier-correction.txt >> maj.patch
La commande patch
La commande patch, quant à elle, est utilisée pour appliquer des différences générées par la commande diff à un fichier source. Elle permet d'appliquer des correctifs ou des modifications à un fichier de manière automatique.
Si la commande n'est pas disponible, on installera le paquet patch.
Voici la syntaxe :
Code BASH :
patch [options] fichier_a_patcher < fichier.patch
Il existe des options utiles :
- -b : Garde une copie du fichier source avec l'extension .orig
- -R : Inverse l'effet de patch (pratique pour "annuler un patch")
Si nous reprenons notre exemple, on imagine que notre destinataire n'a que le fichier (à patcher) livre.txt. On va simplement lui envoyer le fichier maj.patch
On appliquera la modification comme ceci :
Code BASH :
patch livre.txt < maj.patch
Le système indique que l'opération s'est bien déroulée :
Code TEXT :
patching file livre.txt
Pour annuler un patch, avec l'option -R on utilisera la commande comme ceci :
Code BASH :
patch -R livre.txt < correction.patch
Dans le cas où plusieurs fichiers ont été patchés, on utilisera la syntaxe sans spécifier le nom des fichiers à patcher et on aura le retour suivant :
Code TEXT :
patching file livre.txt patching file livre2.txt
Commande patch avec une arborescence différente
Il existe une option intéressante dans le cas où l'arborescence diffère, c'est l'option -pN où :
- -p : Option à patch qui indique de supprimer les premiers N composants des noms de répertoire mentionnés dans le diff avant d'appliquer les modifications.
- N : entier qui spécifie le nombre de composants de chemin à supprimer.
Je prends un exemple où on a un serveur de test où l'arborescence est :
Code :
test/
|- livre.txt
|- livre2.txt
Et le serveur de prod est :
Code :
prod/
|- livre.txt
|- livre2.txt
Si le patch a été fait dans le dossier parent de "test", on a les chemins de fichiers sous cette forme :
Code TEXT :
--- test/livre2.txt 2024-02-13 19:20:42.289398937 +0100 +++ test/livre2-correction.txt 2024-02-13 19:22:43.760479078 +0100
Or, cette arborescence sur le serveur de production n'existe pas, elle est différente.
On ne pourra pas patcher car les fichiers ne se trouvent pas dans le dossier "test".
On placera dans ce cas le patch dans le dossier "prod" directement, et on demandera à patch de supprimer un niveau de répertoire :
Code BASH :
patch -p1 < correction.patch