Formation PUB010 : PHP, 2022 Copie de sécurité (sauvegarde, backup)

7.1 Script pour faciliter la copie de sécurité dans le nuage


Lorsque vous développez un site Web, il importe de copier régulièrement votre code sur un autre support afin d'éviter de tout perdre en cas de bris de disque, de fichier corrompu ou même pour pouvoir reculer dans le temps en cas de besoin.

Voici un petit fichier bash qui s'occupe de :

  • Créer un dossier dans Google Drive (ou dans DropBox ou tout autre espace de stockage synchronisé sur le cloud) dont le nom se termine par la date du jour.
  • Y copier tous les fichier et les sous-dossiers d'un dossier donné.
  • Dans le cas d'une BD MySQL, générer un script SQL qui sera également copié dans le dossier.

Ce fichier peut être utilisé tel quel sous Mac. Si vous travaillez sous Windows, quelques petits ajustements seront nécessaires, tel que présenté plus bas.

En prime, je vous propose également les ajustements nécessaires si vous travaillez sous Devilbox.

Notez que sous Mac, si le fichier porte l'extension .bash ou .sh, il sera possible de l'exécuter seulement à partir d'une fenêtre Terminal (ne pas oublier de mettre « ./ » avant d'écrire son nom lors de l'appel). S'il porte l'extension .command, il sera possible de l'exécuter également en double-cliquant sur son nom dans le Finder.

Toujours sous Mac, vous devez ajouter les droits d'exécution sur ce fichier (voir Exécuter un fichier bash).

Ce que vous avez à faire pour utiliser ce fichier bash :

  • Installez le client Google Drive sur votre poste de travail (ou le client DropBox).
  • Dans le script, entrez les informations désirées dans la section configuration.
  • Lancez le script dès que vous avez terminé une journée de programmation!
Fichier bash

#!/bin/bash
# Copie un dossier et ses sous-dossiers dans le nuage (Google Drive, DropBox ou autre dossier synchronisé sur un serveur)
# en ajoutant la date du jour au dossier principal.
# Crée également un script SQL de la base de données MySQL et le copie dans le même dossier.
# Programmé par Christiane Lagacé : https://christianelagace.com
# Dernier ajustement le 16 janvier 2024

# *************************
# ***** Configuration *****
# *************************

# ***** VOUS DEVEZ REMPLIR CETTE SECTION *****

# Chemin pour accéder au dossier du projet
# (ex sous Mac : "/Applications/AMPPS/www")
# (ex sous Windows : "C:\\Program Files\\Ampps\\www") 
cheminSource="/Applications/AMPPS/www"

# Nom du dossier contenant le projet à sauvegarder (ex : monprojet)
dossierSource=monprojet


# Chemin du dossier infonuagique
# (ex sous Mac : "/Volumes/GoogleDrive/Mon disque")
# (ex sous Windows : "C:\\Users\\MonNom\\Google Drive"
cheminCible="/Volumes/GoogleDrive/Mon disque"

# Nom du dossier dans lequel le projet doit être copié (ex : monprojet)
# Le dossier sera créé sur Google Drive ou DropBox avec la date du jour à la fin de son nom.
dossierCible=monprojet

# Requis seulement si le serveur de bases de données est installé directement sur votre ordinateur (pas dans un conteneur)
# Chemin du dossier qui contient le fichier mysqldump.exe
# (ex sous Mac : "/Applications/AMPPS/mysql/bin" ou /Applications/XAMPP/xamppfiles/bin)
# (ex sous Windows : "C:\\Program Files\\Ampps\\mysql\\bin"
cheminMySQLBin="/Applications/AMPPS/mysql/bin"

# Requis seulement si le serveur de bases de données est installé dans un conteneur
# Nom du conteneur MySQL (docker ps permet de lister les conteneurs)
# (ex : devilbox-mysql-1)
conteneur=devilbox-mysql-1

# Nom de l'usager MySQL qui détient les droit requis pour sauvegarder la base de données
usagerMySQL=root

# Nom de la base de données à sauvegarder
nomBD=mabd

# *****************************
# ***** Fin configuration *****
# *****************************

echo ""
echo "*************************"
echo "***** Copie du site *****"
echo "*************************"
aujourdhui=$(date +%Y-%m-%d)
rsync -arq "$cheminSource/$dossierSource/" "$cheminCible/$dossierCible-$aujourdhui" \
&& okFichiers=true || okFichiers=false

if [ $okFichiers == true ]
then
    echo "Les fichiers ont été copiés dans le dossier"
    echo "$cheminCible/$dossierCible-$aujourdhui"
else
    echo "+------------------------------------------------------------------+"
    echo "| Oups, un problème a été rencontré lors de la copie des fichiers. |"
    echo "+------------------------------------------------------------------+"
fi
echo ""
echo "***********************************************"
echo "***** Création du script pour la BD MySQL *****"
echo "***********************************************"
mkdir -p "$cheminCible/$dossierCible-$aujourdhui/dev"
cd "$cheminMySQLBin"
./mysqldump -u $usagerMySQL -p --default-character-set=utf8 --routines --comments --triggers $nomBD > "$cheminCible/$dossierCible-$aujourdhui/dev/$nomBD-$aujourdhui.sql" \
&& okBD=true || okBD=false

if [ $okBD == true ]
then
    echo "La base de données est exportée dans le fichier"
    echo "$cheminCible/$dossierCible-$aujourdhui/dev/$nomBD-$aujourdhui.sql"
else
    echo "+--------------------------------------------------------------------+"
    echo "| Oups, un problème a été rencontré lors de la génération du script. |"
    echo "+--------------------------------------------------------------------+"
fi

Si la base de données est dans un conteneur Docker

Si vous travaillez dans un environnement qui utilise des conteneurs Docker, par exemple avec Devilbox, vous devrez apporter un petit ajustement au script.

Tout le contenu de la section sur la création du script devra être remplacé par ceci.

Fichier bash

mkdir -p "$cheminCible/$dossierCible-$aujourdhui/dev"

docker exec -it -e nomBD=$nomBD -e usagerMySQL=$usagerMySQL -e aujourdhui=$aujourdhui $conteneur bash -c "/usr/bin/mysqldump -u ${usagerMySQL} -p --default-character-set=utf8 --routines --comments --triggers ${nomBD} > /${nomBD}-${aujourdhui}.sql" \
&& okBD=true || okBD=false

if [ $okBD == true ]
then
    docker cp $conteneur:/$nomBD-$aujourdhui.sql "$cheminCible/$dossierCible-$aujourdhui/dev"
    docker exec -it $conteneur bash -c "rm /$nomBD-$aujourdhui.sql"
    echo ""
    echo "La base de données est exportée dans le fichier"
    echo "$cheminCible/$dossierCible-$aujourdhui/dev/$nomBD-$aujourdhui.sql"
else
    echo "+--------------------------------------------------------------------+"
    echo "| Oups, un problème a été rencontré lors de la génération du script. |"
    echo "+--------------------------------------------------------------------+"
fi

Exclusion de fichiers ou de dossiers

Notez qu'il est possible d'exclure certains fichiers ou sous-dossiers. Si tel est votre désir :

  • Créez un fichier texte dans lequel vous listerez les fichiers et dossiers à exclure.

    Vous devez placer un seul fichier ou dossier à exclure par ligne.

    Les dossiers débuteront par \ et se termineront par \.

    Assurez-vous que le nom de votre fichier texte soit significatif car il sera utilisé dans votre commande XCOPY.

    Fichier fichiers-exclus.txt contenant la liste des fichiers et dossiers à exclure

    \nomdossier\

    unfichieralaracine.php
    \autredossier\unfichierdanssousdossier.jpg
  • Dans votre fichier bash, modifiez la ligne rsync pour y ajouter, à la toute fin, l'option exclude. 
    Fichier bash

    rsync -arq "$cheminSource/$dossierSource/" "$cheminCible/$dossierCible-$aujourdhui" \
    --exclude-from fichiers-exclus.txt \

Ajustements pour Windows

Ce script pourra rouler sous Windows dans une fenêtre Git Bash (et non dans PowerShell).

Vous devrez apporter quelques ajustements au script.

  • Dans les variables qui définissent des chemins ainsi que partout dans les chemins entre guillemets, les barres obliques doivent être remplacées par des barres obiques inverses doublées. Ex : C:\\Users\\MonNom\\Google Drive.
  • La commande rsync n'existe pas sous Windows. Vous avez deux choix :
    • installer un paquet qui permet de faire un rsync (https://terokarvinen.com/rsync_from_windows.html)

      ou

    • remplacer l'instruction par celle-ci :
      Fichier bash sous Windows

      cp -rf "$cheminSource\\$dossierSource\\" "$cheminCible\\$dossierCible-$aujourdhui" \
      && okFichiers=true || okFichiers=false

  • Dans la version pour Devilbox, les caractères de fin de ligne devront être ajustés pour le monde Linux. Sous Geany : Document / Définir les fins de ligne / Convertir en LF (Unix).
  • La commande mysqldump ne s'arrêtera pas pour vous demander le mot de passe lorque lancée dans un script bash sous Windows. Si le mot de passe n'est pas à blanc (sous DevilBox, le mot de passe par défaut est à blanc), vous devez inscrire le mot de passe directement dans le script.
    Fichier bash sous Windows

    # Mot de passe MySQL (pour Windows seulement)
    motDePasse=mysql
    ...
    ./mysqldump -u $usagerMySQL -p$motDePasse --default-character-set=utf8 --routines --comments --triggers $nomBD > "$cheminCible/$dossierCible-$aujourdhui/dev/$nomBD-$aujourdhui.sql" && echo OK || echo "Oups, un problème a été rencontré lors de l'exportation de la base de données."

    Notez qu'il existe une technique plus sécuritaire pour fournir le mot de passe mais puisqu'il s'agit du mot de passe par défaut de votre SGBD, c'est acceptable de le laisser directement dans le script.
  • Dans la version pour Devilbox, à chaque fois que la commande docker est utilisée, vous devrez plutôt écrire docker.exe.
  • Dans la version pour Devilbox, la commande qui génère le script SQL devra être remplacée par la suivante (ajout de winpty pour éviter l'erreur « the input device is not a TTY » et commande bash entre apostrophes et qui débute par un \ pour éviter l'erreur « C:/Program: No such file or directory ») :
    Fichier bash sous Windows avec Devilbox

    winpty docker.exe exec -it -e nomBD=$nomBD -e usagerMySQL=$usagerMySQL -e aujourdhui=$aujourdhui $conteneur bash -c '\/usr/bin/mysqldump -u ${usagerMySQL} -p --default-character-set=utf8 --routines --comments --triggers ${nomBD} > /${nomBD}-${aujourdhui}.sql' \
    && okBD=true || okBD=false

  • La commande winpty devra également être ajoutée devant la ligne qui supprime le script SQL dans le conteneur.
    Fichier bash sous Windows avec Devilbox

    winpty docker.exe exec -it $conteneur bash -c "rm /$nomBD-$aujourdhui.sql"

  • Pour lancer le script, ouvrez une fenêtre Git Bash puis placez-vous dans le dossier qui contient votre script. Vous devrez précéder le nom du script par bash et ne pas oublier l'extension, peu importe si c'est .sh, .bash ou .command.
  • Terminal sous Windows

    cd chemin/du/fichier
    bash nomfichier.bash

  • Notez que dans la version pour Devilbox, si vous obtenez le message « world-writable config file '/etc/mysql/conf.d/devilbox.cnf' is ignored », le script fonctionnera tout de même.

Ancienne version batch pour Windows

Si vous êtes nostalgiques des fichiers batch ou si vous n'avez pas installé WSL sur votre ordinateur Windows, vous pouvez travailler avec le fichier batch que je vous présente ici.

Note : pour que les accents présents dans les echo soient correctement affichés sous Windows, le fichier doit être encodé au format IBM850 (dans Geany : Fichier / Recharger en tant que / Européen de l'ouest / Occidental (IBM850)).

Certains éditeurs offrent plutôt le format OEM 720 (dans Notepad++ : Encodage / Codage de caractères / Arabe / OEM 720).

Fichier batch

@ECHO OFF
REM Copie un dossier et ses sous-dossiers dans le nuage (Google Drive, DropBox ou autre dossier synchronisé sur un serveur)
REM en ajoutant la date du jour au dossier principal.
REM Crée également un script SQL de la base de données MySQL et le copie dans le même dossier.
REM Note : Pour que les accents présents dans les echo s'affichent correctement, utiliser l'encodage IBM850 ou OEM 720.
REM Note : Si des noms de dossiers contiennent des caractères accentués, utilisez l'encodage Windows 1252 ou ANSI
REM        et ajoutez l'instruction CHCP 1252.
REM Programmé par Christiane Lagacé : https://christianelagace.com
REM Le 26 mars 2013
REM Dernier ajustement par Christiane Lagacé
REM Le 28 janvier 2020
REM Modifications : Chemins suggérés ajustés pour AMPPS.
 
REM *************************
REM ***** Configuration *****
REM *************************
 
REM ***** VOUS DEVEZ REMPLIR CETTE SECTION *****
 
REM Chemin pour accéder au dossier du projet. Placer entre guillemets s'il contient des espaces.
REM (ex : "C:\Program Files\Ampps\www")
set cheminSource="C:\Program Files\Ampps\www"
 
REM Nom du dossier contenant le projet à sauvegarder (ex : monprojet)
set dossierSource=monprojet
 
REM Chemin du dossier infonuagique (ex : C:\Users\MonNom\Google Drive)
set cheminCible="C:\Users\MonNom\Google Drive"
 
REM Nom du dossier dans lequel le projet doit être copié (ex : monprojet)
REM Le dossier sera créé sur Google Drive ou DropBox avec la date du jour à la fin de son nom.
set dossierCible=monprojet
 
REM Chemin du dossier contenant le fichier mysqldump.exe 
REM (ex : "C:\Program Files\Ampps\mysql\bin")
set cheminMySQLBin="C:\Program Files\Ampps\mysql\bin"
 
REM Nom de l'usager MySQL qui détient les droit requis pour sauvegarder la base de données
set usagerMySQL=root
 
REM Nom de la base de données à sauvegarder
set nomBD=mabd
 
REM *****************************
REM ***** Fin configuration *****
REM *****************************
 
REM ***** Création des variables pour la date *****
REM La commande "WMIC OS GET localdatetime" retrouve la date au format ISO. 
REM Le caractère ^ (caret) est un caractère d'échappement.
REM Le caractère | (pipe) permet de rediriger la sortie de WMIC vers la commande find. 
REM Puisqu'on veut conserver toute la chaîne, on recherche n'importe quel caractère : find "."
REM Autrement dit, cette ligne place toute la date dans la variable dateISO.
 
for /f %%a in ('WMIC OS Get localdatetime  ^| find "."') do set dateISO=%%a
set annee=%dateISO:~0,4%
set mois=%dateISO:~4,2%
set jour=%dateISO:~6,2%
 
echo *************************
echo ***** Copie du site *****
echo *************************
 
@echo on
XCOPY %cheminSource%\%dossierSource%\* %cheminCible%\%dossierCible%-%annee%-%mois%-%jour% /S /I
@echo off
 
echo ***********************************************
echo ***** Création du script pour la BD MySQL *****
echo ***********************************************
 
@echo on
CD %cheminMySQLBin%
mysqldump -u %usagerMySQL% -p --default-character-set=utf8 --routines --comments --triggers %nomBD% > %cheminCible%\%dossierCible%-%annee%-%mois%-%jour%\%nomBD%-%annee%-%mois%-%jour%.sql
@echo off
 
echo *******************
echo ***** Terminé *****
echo *******************
echo.
echo Les fichiers ont été copiés dans le dossier
echo %cheminCible%\%dossierCible%-%annee%-%mois%-%jour%
echo.
PAUSE

Notez que dans la commande XCOPY, l'option /S signifie qu'il faut copier les sous-dossiers non vides et l'option /I indique que si la destination n'existe pas et que plus d'un fichier est copié, la destination sera considérée comme un dossier.

Chemin contenant des caractères accentués

Je crois que tout le monde s'entend là-dessus : on devrait éviter à tout prix d'utiliser des caractères accentués dans les noms de fichiers et dans les noms de dossiers. Malheureusement, certains développeurs ne se sont pas conformés à cette bonne pratique alors il arrive des cas où nous devons tout de même composer avec des caractères accentués.

Si c'est votre cas, les précautions suivantes vous permettront d'adapter votre fichier batch pour qu'il puisse copier le contenu d'un dossier dont le chemin contient des caractères accentués.

  • Pour que les caractères accentués dans les noms de dossiers puissent être correctement interprétés, changez l'encodage du fichier pour Windows 1252 ou ANSI. Les caractères accentués déjà présents dans le fichier apparaîtront sous forme de caractères bizarre. Vous pouvez les laisser tels quels. Cependant, les accents dans les noms de dossiers devront être écrits correctement sous cet encodage.
  • Au début de votre script, vous devez indiquer que les instructions contenues dans le script utilisent la page de code « Windows Latin 1 (ANSI) ». Ceci se fait à l'aide de la commande CHCP suivie du numéro correspondant à la page de code désirée, soit le 1252.
Fichier batch

CHCP 1252

...

set cheminCible="C:\Users\Étienne\Google Drive"

...

XCOPY ...

...

Pour plus d'information

« Code Pages ». MSDN. http://msdn.microsoft.com/en-us/library/windows/desktop/dd317752%28v=vs.85%29.aspx

« Code Page Identifiers ». MSDN. http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx

▼Publicité

Veuillez noter que le contenu de cette fiche vous est partagé à titre gracieux, au meilleur de mes connaissances et sans aucune garantie.
Merci de partager !
Soumettre