Comment utiliser Inotify et RSYNC pour créer un système de sauvegarde en direct

Comment utiliser Inotify et RSYNC pour créer un système de sauvegarde en direct

Pourquoi devriez-vous utiliser des scripts bash pour effectuer des synchronisations et des sauvegardes de dossiers?

Bash est de loin l'interprète de langue de commande compatible SH le plus populaire et le plus utilisé. Aujourd'hui, vous pouvez trouver Bash presque partout, y compris Microsoft Windows avec le nouveau sous-système Windows pour Linux. Pratiquement toute la distribution GNU / Linux est livrée avec Bash comme coque par défaut. Il en va de même pour MacOS et certains autres systèmes d'exploitation de type Unix.

Bash n'est pas seulement un langage de commande; Comme d'autres coquilles Unix, Bash est à la fois un langage de programmation et un interprète de commande. Techniquement parlant, le côté de programmation d'un shell donne les capacités et les fonctionnalités des utilisateurs pour combiner le système ou les utilitaires de shell dans un fichier. L'utilisateur peut créer des commandes simplement en combinant des commandes dans un fichier texte; Ces types spéciaux de fichier texte qui incluent une collection de commandes sont appelés scripts shell et, lorsque ces fichiers reçoivent l'autorisation d'exécuter, l'interprète shell les considère comme une seule commande.

L'avantage d'un script bash est que vous pouvez utiliser des outils de ligne de commande directement à l'intérieur sans avoir besoin d'importation ou de bibliothèques externes d'importation. Ces outils de ligne de commande et les services publics intégrés sont puissants et peuvent interagir directement avec le système d'exploitation sans compilation ou interprètes supplémentaires; Habituellement, les utilitaires de base et les interfaces de ligne de commande, comme awk, xargs, trouver, et grep, peut avoir une bien meilleure performance que l'utilisation de scripts Python et de ses bibliothèques par exemple. Il n'est pas difficile de trouver des personnes effectuant une analyse avancée des données en utilisant uniquement des services publics de script et de GNU intégrés GNU. D'autres affirment que ce type d'approche peut être 235 x plus rapide qu'un cluster Hadoop - ce qui n'est pas si difficile à croire compte tenu de certaines monstruosités de clustering que vous pouvez trouver de nos jours juste pour convenir à de mauvaises conceptions de logiciels.

Dans cette affaire, une question se pose toujours: si Bash est si puissant, pourquoi ne pas l'utiliser pour automatiser toutes les choses ennuyeuses? La syntaxe bash est simple et pragmatique: elle vous donne la possibilité de combiner des programmes pour automatiser les tâches communes. Cependant, lorsque le script doit faire face à plusieurs conditions ou accumuler trop d'objectifs, il est temps de considérer un langage de programmation plus robuste, comme C ou d'autres langages de script, où Python et Perl sont de bons exemples.

D'un autre côté, les scripts bash sont très bons pour les tâches uniques comme l'intention de cet article: combiner des services publics avec des capacités pour vérifier les modifications d'un dossier spécifique, puis synchroniser ses fichiers. Un script bash peut parfaitement convenir à cette tâche.

De quoi avez-vous besoin pour effectuer la syncronisation ou les autobackups?

Il existe une grande liste de différentes méthodes pour synchroniser les dossiers et les fichiers. Le nombre d'applications qui peuvent être utilisés pour accomplir cette tâche simple est vaste, et certaines d'entre elles sont des solutions tierces. Cependant, Cet article vous montre un moyen plus élégant de réaliser la même chose en utilisant uniquement inotifywait et rsync Dans un script bash. En général, cette solution sera légère, peu coûteuse et, pourquoi ne pas dire, plus sûre. Essentiellement, seuls les outils inotifier, RSYNC et une boucle de temps sont nécessaires pour terminer cette mission.

Comment utiliser InotifyWait pour les autobacks et les syncronisations?

inotifywait Utilise Inotify API pour attendre les modifications des fichiers. Cette commande a été spécialement conçue pour être utilisée dans les scripts shell. Une caractéristique puissante de inotifywait est de vérifier les modifications en continu; Dès que de nouveaux événements se produisent, inotifywait imprime les modifications et les sorties.

inotifywait Fournit deux options très intéressantes pour la synchronisation des dossiers ou les sauvegardes en temps réel. Le premier est le -r, -récursif option; Comme son nom l'indique, ce drapeau regarde des sous-répertoires illimités les profondeurs d'un répertoire spécifique passé comme arguments à inotifywait, à l'exclusion des liens symboliques.

Le -e, -événement Le drapeau fournit une autre fonctionnalité intéressante. Cette option nécessite une liste d'événements prédéfinis. La documentation Inotify-Tool répertorie plus de 15 événements pour inotifywait; Mais un simple système de sauvegarde et de synchronisation nécessite uniquement les événements de suppression, de modification et de création.
La commande suivante est un bon exemple d'un scénario du monde réel:

$ inotifywait -r -e modifier, créer, supprimer / home / userdir / documents

Dans ce cas, la commande attend des modifications - modifications, créations de fichiers ou de dossiers ou exclusions de toute nature - dans le fictif / Home / Userdir / Documents annuaire. Dès que l'utilisateur apporte un changement, inotifywait Sorte la modification et la sortie.

En supposant que vous créez un nouveau fichier appelé nouveau fichier à l'intérieur de Documents dossier pendant que le inotifywait Le surveillance. Une fois que la commande détecte la création de fichiers, il produit

Documents / créer newfile

Autrement dit, inotifywait imprime où la modification se produit, quel type de modifications il a apporté et le nom du fichier ou du dossier qui a été modifié.

Examiner le statut de sortie de inotifywait Lorsqu'un changement a lieu, vous voyez un statut de 0ex qui signifie une exécution réussie. Cette situation est parfaite pour un script shell car un statut de sortie peut être utilisé comme une vraie ou fausse condition.

Par conséquent, la première étape du script est complète: pour trouver un utilitaire qui attend des changements dans les répertoires. Le second est de rechercher un utilitaire capable de synchroniser deux répertoires, et rsync est un candidat parfait.

Comment utiliser RSYNC pour Autobackups?

rsync est une application puissante. Vous pouvez écrire un livre décrivant tout ce que vous pouvez faire avec cet utilitaire polyvalent. Techniquement parlant, rsync n'est rien de plus qu'un outil de co-coffre, une sorte de CP commande avec des stéroïdes et des pouvoirs spéciaux comme les fichiers de transfert sécurisés. L'utilisation de rsync dans ce script est plus modeste mais pas moins élégant.

L'objectif principal est de trouver un moyen de:

  • Se reproduire dans les répertoires;
  • Copier les liens symboliques comme liens symboliques;
  • Préserver les autorisations, la propriété, les groupes, le temps de modification, les appareils et les fichiers spéciaux;
  • Fournir des détails supplémentaires, sortie verbeux - il est donc possible de créer un fichier journal si nécessaire;
  • Compressez les fichiers pendant le transfert pour l'optimisation.

Le rsync La documentation est bien écrite; Vérification du résumé des options disponibles, vous pouvez facilement sélectionner le -avz drapeaux comme le meilleur choix. Une utilisation simple ressemble à ce qui suit:

rsync -avz / /

Il est important de mettre une barre oblique après le dossier d'origine. Au contraire, rsync Copie l'ensemble du dossier d'origine (y compris lui-même) dans le dossier de destination.

Par exemple, si vous créez deux dossiers, un appelé oriental et l'autre dossier de destination, faire rsync Envoyer au second chaque modification apportée à la première, utilisez la commande suivante:

$ RSYNC -AVZ ORENENFOLDER / DESTINEFOLDER

Une fois que vous avez créé un nouveau fichier nommé nouveau fichier, rsync Imprime quelque chose comme:

Envoi de liste de fichiers incrémentiels
./ /
nouveau fichier
Envoyé 101 octets reçus 38 octets 278.00 octets / sec
La taille totale est de 0 accélération est 0.00

Dans la première ligne, la directive imprime le type de processus, une copie incrémentielle; cela signifie que le rsync utilise ses capacités de compressions pour ne pas augmenter le fichier et ne pas modifier l'ensemble des archives. Comme c'est la première fois que la commande est exécutée, l'application copie l'ensemble du fichier; Une fois que de nouveaux changements se produisent, seules les incrémentations ont lieu. La sortie suivante est l'emplacement, le nom de fichier et les données de performances. Vérification du statut de sortie du rsync Commande, vous recevez un 0-EXIT pour une exécution réussie.

Ainsi, il existe deux applications importantes pour apporter la prise en charge de ce script: l'une est capable d'attendre des modifications, et l'autre peut créer des copies de cette modification en temps réel. Ici, ce qui manque est un moyen de connecter les deux services publics rsync prend des mesures dès que inotifywait perçoit toute modification.

Pourquoi nous avons besoin d'une boucle de temps?

La solution la plus simple pour le problème ci-dessus est une boucle. En d'autres termes, à chaque occasion inotifywait existe avec succès, le script bash doit appeler rsync pour effectuer son incrément; Immédiatement après la copie, le shell doit revenir à l'état initial et attendre une nouvelle sortie du inotifywait commande. C'est exactement ce que fait une boucle.

Vous n'avez pas besoin d'une vaste expérience en programmation pour écrire un script bash. Il est très courant de trouver de bons administrateurs système qui n'ont pas, ou très limité, une expérience de programmation. Cependant, La création de scripts fonctionnels est toujours une tâche importante de l'administration du système. La bonne nouvelle est que le concept derrière une boucle de temps est facile à comprendre.

Le diagramme suivant représente une boucle while:

Diagramme infini dans la boucle.

UN représente le inotifywait Commande discutée ci-dessus et B, rsync. À chaque fois UN Existe avec un statut 0-Exit, le shell l'interprète comme vrai; Ainsi, la boucle while permet l'exécution de B; dès que B Sorte également avec succès, la commande revient à UN encore et répète la boucle.
Dans ce cas, la boucle while évalue toujours vrai pour UN. Techniquement, il génère une boucle infinie, ce qui est bon pour la proposition de ce script; inotifywait sera exécuté de manière récurrente, ce qui signifie qu'elle attendra toujours de nouvelles modifications.

Plus formellement, la syntaxe pour un bash pendant la boucle est:

alors que
faire

fait

signifie la liste des conditions (UN) Cela doit être vrai; Ainsi, la boucle while peut exécuter le , Debout pour le bloc de commandes (B). Si la boucle de pré-test UN est faux, alors la boucle while sort sans exécuter B.

Voici comment rsync et inotifywait Les commandes s'inscrivent à l'intérieur de la boucle while,

Pendant l'inotifywait -r -e modifier, créez, supprimez Origène
faire
RSYNC -AVZ ORENENFOLDER / DESTINEFOLDER
fait

Combiner tout

Il est maintenant temps de combiner tout ce qui est discuté ci-dessus pour créer un script shell. La première chose est de créer un fichier vide et de le nommer; par exemple, livebackup.frapper représente un bon choix. Il est global de placer des scripts shell dans le dossier bin sous le répertoire de la maison utilisateur, un.k.un. $ Home / bin.

Après cela, vous pouvez modifier le fichier dans l'éditeur de texte de votre choix. La première ligne d'un script bash est très importante; C'est là que le script définit la directive interprète, par exemple:

#! [Options]

Le shebang est ce symbole étrange avec un hachage et une marque d'exclamation (#!). Lorsque le shell charge le script pour la première fois, il recherche ce signe, car il indique ce que l'interprète doit être utilisé pour exécuter le programme. Le shebang n'est pas un commentaire, et il doit être placé en haut du script sans espaces au-dessus.

Vous pouvez laisser la première ligne vide et ne pas définir l'interprète. De cette façon, le shell utilise l'interpréteur par défaut pour charger et exécuter le script, mais il n'est pas approuvé. Le choix le plus approprié et le plus sécurisé est d'indiquer la directive d'interprète comme suit:

#!/ usr / bin / bash

Avec la directive d'interprète explicite comme celle-là, le shell recherche l'interprète bash dans le répertoire / usr / bin. Comme la tâche de ce script est simple, il n'est pas nécessaire de spécifier plus de commandes ou d'options. Une possibilité plus sophistiquée est d'appeler l'interprète en utilisant la commande env.

#!/ usr / bin / env bash

Dans ce contexte, le shell recherche la commande bash par défaut dans l'environnement actuel. Un tel arrangement est utile lorsque l'environnement utilisateur a des personnalisations importantes. Cependant, cela peut entraîner des pépins de sécurité au niveau de l'entreprise une fois que le shell n'est pas en mesure de détecter si la commande dénigrer dans un environnement personnalisé est ou n'est pas un interprète sûr.

Lorsque vous assemblez tout à ce stade, le script ressemble:

#!/ usr / bin / bash
Pendant l'inotifywait -r -e modifier, créer, supprimer Originfolder
faire
RSYNC -AVZ ORENENFOLDER / DESTINEFOLDER
fait

Comment utiliser les arguments dans un script bash?

Ce qui sépare ce script d'une fonctionnalité totale, c'est comment il définit l'origine et le dossier de destination. Par exemple, il est nécessaire de trouver un moyen de montrer ce que sont ces dossiers. Le mode plus rapide pour résoudre cette question consiste à utiliser des arguments et des variables.

Voici un exemple de la bonne façon de se référer au script:

$ ./ livebackup.bash / home / utilisateur / origine / home / utilisateur / destination

Le shell charge l'un de ces arguments tapés après le nom du script et les transmet au chargeur de script sous forme de variables. Par exemple, le répertoire / Home / User / Origin est le premier argument, et vous pouvez y accéder à l'intérieur du script en utilisant le 1 $. Ainsi, 2 $ a une valeur de / Home / User / Destination. Toutes ces variables de position sont accessibles en utilisant le signe du dollar ($) suivi par un nombre n ($ n), où n est la position de l'argument où le script est appelé.

Le signe du dollar ($) a une signification et des implications très particulières à l'intérieur des scripts shell; Dans d'autres articles, il sera discuté en profondeur. Pour l'instant, le puzzle est presque résolu.

#!/ usr / bin / bash
Pendant l'inotifywait -r -e modifier, créer, supprimer 1 $
faire
RSYNC -AVZ 1 $ / 2 $
fait

Note: Pour faire face à trop d'arguments en utilisant uniquement des paramètres de position ($ n) peut rapidement conduire à de mauvaises conceptions et à la confusion dans les scripts de coquille. Un moyen plus élégant de résoudre ce problème est d'utiliser le getopts commande. Cette commande vous aide également à créer des alertes de mauvais usage, ce qui peut être utile lorsque d'autres utilisateurs ont accès au script. Une recherche rapide sur Internet peut afficher différentes méthodes d'utilisation getopts, Qu'est-ce qui peut améliorer le script actuel si vous avez besoin de donner plus d'options d'utilisation à d'autres utilisateurs.

Le faire exécutable

Une seule chose de plus doit être faite maintenant: faire le fichier livebackup.frapper exécutable. Il peut être facilement effectué avec le chod commande.

Allez dans le dossier contenant le script et type:

$ chmod + x livebackup.frapper

Ensuite, tapez le signe de slash dot (./) Avant le nom du script. Le DOT signifie, dans ce contexte, le répertoire actuel et la barre oblique définit un chemin relatif vers le fichier dans le répertoire actuel. Dans cet esprit, vous devez également taper le dossier d'origine comme le premier argument, suivi du dossier de destination comme deuxième, comme:

$ ./ livebackup.bash / home / utilisateur / origine / home / utilisateur / destination

Alternativement, vous pouvez appeler les scripts par son nom plaçant son emplacement de dossier dans le chemin de l'environnement ou l'appeler une sous-coquille, comme:

$ bash livebackup.bash / home / utilisateur / origine / home / utilisateur / destination

La première option est cependant un choix sécurisé.

Exemple de la vie réelle

Dans un scénario du monde réel, Exécuter manuellement un script de sauvegarde chaque fois que vous démarrez le système, peut être fastidieux. Un bon choix est d'utiliser un Tâche planifiée ou chronomètre/ /service unités avec systemd. Si vous avez de nombreux dossiers différents à sauvegarder, vous pouvez également créer un autre script qui s'approvisionne livebackup.frapper; Ainsi, la commande ne doit être appelée qu'une seule fois dans un .service unité. Dans un autre article, cette fonctionnalité peut être discutée plus en détail.

Si vous utilisez le sous-système Windows pour Linux, il est possible de créer une tâche de base pour exécuter votre script à l'aide du «Task Scheduler» qui est déclenché par le démarrage du système. Pour utiliser un fichier batch pour appeler le frapper.exe avec une liste de commandes est un bon choix. Vous pouvez également utiliser un script Visual Basic pour lancer le fichier batch en arrière-plan.

À quoi ressemble un script pro bash

Voici un exemple de script conçu par l'auteur qui peut lire plus d'arguments de ligne de commande sophistiqués.

#!/ usr / bin / env bash
#
#################################################### ########################################
#################################################### ########################################
#
# Script: syncolder.frapper
# Auteur: Diego Aurino da Silva
# Date: 16 février 2018
# Rev: 1.0
# Licence: MIT (https: // github.com / diegoaurino / bashscripts / blob / maître / licence)
#
# Plateforme: WSL ou GNU / Linux
#
# Objectif: petit script pour synchroniser les changements de gauche à droite à partir de deux dossiers
# sous WSL ou GNU / Linux (nécessite des outils inotifiers)
#
#################################################### ########################################
#################################################### ########################################
##################
# RÉGLAGES GÉNÉRAUX
##################
gras = $ (tput bold)
normal = $ (tput sgr0)
Origène = ""
destination = ""
##################
# Section Options
##################
Si [$ # -eq 0]
alors
printf "\ n% s \ t \ t% s \ n \ n" "utiliser $ bold -h $ normal pour l'aide."
sortie 1
autre
tandis que les getopts ": h" l'option
faire
cas $ option dans
h)
printf "\ n% s \ t \ t% s \ n \ n" "Utilisation: ./ Syncfolder.bash $ bold / origine / dossier $ normal -o $ bold / destination / dossier $ normal "
sortie 0
;;
\? )
printf "\ n% s \ n \ n" "$ bold Option invalide pour $ normal $ (nom de base $ 0)" 1> & 2
sortie 1
;;
ESAC
fait
Shift $ ((Optind -1))
Origène = 1 $
changement
tandis que les getopts ": o:" Option
faire
cas $ option dans
o)
destination = $ optarg
printf "\ n% s \ n \ n" "Les dossiers suivants seront synchronisés à gauche:"
printf "\ torigen: \ t \ t \ t% s \ n" "$ bold $ origine $ normal"
printf "\ tdestination: \ t \ t% s \ n \ n" "$ bold $ destination $ normal"
;;
\? )
printf "\ n% s \ n \ n" "$ bold Option non valide pour $ normal $ (nom de base $ 0): - $ optarg."1> & 2
sortie 1
;;
:)
printf "\ n% s \ n \ n" "$ bold L'option $ normal - $ optarg nécessite un répertoire comme argument."1> & 2
sortie 1
;;
*)
printf "\ n% s \ n \ n" "$ bold Option Unkown pour $ normal $ (nom de base $ 0): - $ optarg."1> & 2
sortie 1
;;
ESAC
fait
Shift $ ((Optind -1))
Fi
##################
# Section de synchronisation
##################
Pendant l'inotifywait -r -e modifier, créer, supprimer $ origène
faire
RSYNC -AVZ $ ORIGEN / $ Destination - Delete --filter = 'P .git '
fait

Défis

Comme défi, essayez de concevoir deux autres versions du script actuel. Le premier doit imprimer un fichier de journal qui stocke chaque changement trouvé par le inotifywait commande et chaque incrément réalisée par rsync. Le deuxième défi consiste à créer un système de synchronisation à deux directions en utilisant seulement une boucle de temps comme le script précédent. Un conseil: c'est plus facile qu'il n'y paraît.

Vous pouvez partager vos résultats ou questions sur Twitter @LinuxHint