Prochaine révision | Révision précédente |
tp3 [2019/01/22 09:08] – created gilles | tp3 [2021/03/01 10:34] (Version actuelle) – [Q.1 - Création de l'environnement de travail] gilles |
---|
==== En préalable ==== | ==== En préalable ==== |
| |
:!: Etant donné que ce TP est de nature assez sensible dans la mesure où vous êtes sensé effacer des fichiers pour pouvoir tester vos différentes réponses, nous vous encourageons à isoler ce travail et à créer un dossier dédié à sa réalisation. | Etant donné que ce TP est de nature assez sensible dans la mesure où vous êtes sensé effacer des fichiers pour pouvoir tester vos différentes réponses, nous vous encourageons à isoler ce travail et à créer un dossier dédié à sa réalisation. |
| |
Les fichiers nécessaires au fonctionnement de l'environnement de corbeille seront stockés dans un dossier caché nommé **''.sh-trash''** qui se trouvera à la racine de votre //HOME directory//. C'est dans ce dossier que vous stockerez les shell-scripts répondant aux diverses questions de ce TP. | ==== Q.1 - Création de l'environnement de travail ==== |
| |
---- | Créez, sur votre compte un dossier nommé ''tp-corbeille''. Afin de ne pas endommager votre compte, l'ensemble des commandes que vous réaliserez et que vous testerez devrons l'être dans dossier. Pour ce faire, ** tous vos ''bash''-scripts devrons commencer par : ** |
| |
==== Questions ==== | <code bash> |
| #!/bin/bash |
| working_directory=tp-corbeille |
| if ! pwd | grep $working_directory; then |
| echo "Vous n'êtes pas dans le dossier $working_directory !!" |
| exit 1 |
| fi |
| </code> |
| |
| ou sans écho écran |
| |
| <code bash> |
| #!/bin/bash |
| working_directory=tp-corbeille |
| if ! pwd | grep $working_directory > /dev/null 2>&1 ; then |
| echo "Vous n'êtes pas dans le dossier $working_directory !!" |
| exit 1 |
| fi |
| </code> |
| |
| Cet //en-tête// de script pourra être modifié en substituant la seconde ligne par ''working_directory=$HOME'' |
| |
| Les ''bash''-scripts de ce TP nécessaires au fonctionnement de l'environnement de corbeille seront stockés, in fine, dans un dossier caché nommé **''$HOME/.sh-trash''**. Créez ce dossier dés à présent. |
| |
---- | ---- |
| |
* Q.1: La corbeille de votre compte sera stockée dans un dossier nommé <<''.sh-trashbox''>> se trouvant à la racine de votre compte. Ecrivez un script ''check-config.sh'' qui vérifie l'existence du dossier <<''.sh-trashbox''>>. S'il n'existe pas, ce dossier devra être créé. A l'issue de cette phase d'initialisation de la corbeille par ''check-config.sh'', le dossier <<''.sh-trashbox''>> devra contenir deux fichiers: | ==== Q.2 - Initialisation de l'environnement ==== |
* ''ID'' : Un fichier texte contenant le numéro d'ordre du prochain fichier qui sera supprimé. A l'issue de cette initialisation ''ID'' devra contenir << **1** >> | |
* ''INDEX'' : Un fichier texte destiné à contenir l'index des correspondances entre les noms des fichiers supprimés et leur nom de stockage dans la corbeille. A l'issue de cette initialisation ''INDEX'' existera mais sera vide. | Votre **corbeille** de votre compte sera stockée dans un dossier nommé <<''.sh-trashbox''>> se trouvant dans le ''working_directory'' de votre compte. Ecrivez le ''bash''-script ''init-trashbox.sh'' qui vérifie l'existence du dossier <<''.sh-trashbox''>>. S'il n'existe pas, ce dossier devra être créé. A l'issue de cette phase d'initialisation de la corbeille par ''init-trashbox.sh'', le dossier <<''.sh-trashbox''>> devra contenir deux fichiers: |
| |
| * ''ID'' : Un fichier texte contenant la valeur << **1** >>. Le fichier ''ID'' contient le numéro d'ordre du prochain fichier qui sera transféré dans la corbeille. Pour une corbeille vide, le numéro d'ordre du prochain fichier à transférer dans cette corbeille est donc **1** ; |
| |
| |
| * ''INDEX'' : Deux fichiers du SGF à différents endroits mais ayant le même nom ne doivent pas être //écrasés// lors de leur mise à la corbeille. Par ailleurs, ils doivent pouvoir être ressortis de la corbeille indépendamment l'un de l'autre. Le fichier ''INDEX'' sert à assurer la correspondance d'un fichier de la corbeille - qui aura un nom unique - avec son nom << réel >> dans le SGF. Ainsi ''INDEX'' est un fichier texte destiné à contenir l'index des correspondances entre les noms des fichiers supprimés et leur nom de stockage dans la corbeille. A l'issue de la phase d'initialisation ''INDEX'' existe mais sera vide. |
| |
---- | ---- |
| |
* Q.2: Ecrivez un script ''my-ls.sh'' qui prend en paramètre une ou plusieurs entrées du SGF (fichier ou dossier) et qui liste sur la sortie standard pour l'ensemble de ces points d'entrée, leur nom précédé de leur chemins d'accès absolu. | ==== Q.3 - Lister des dossiers et des fichiers sans LS ==== |
| |
| Ecrivez un ''bash''-script, nommé ''my-ls.sh'' admettant un nombre variable de paramètres. Ces paramètres peuvent être des dossiers ou des fichiers. ''my-ls.sh'' renvoie sur la sortie standard la valeur du paramètre s'il correspond à une entrée dans le système de gestion de fichiers et un message d'erreur sinon. ** A NOTER : Vous n'avez pas le droit d'utiliser la commande ''ls'' au sein de ''my-ls.sh'' **. Un exemple. |
| |
| <code bash> |
| $> pwd |
| /users/etud/michu/tp-corbeille |
| |
| $> ls -l |
| drwxrwxrwx 11 michu staff 352 1 oct 15:58 dir-1 |
| -rwxrwxrwx@ 1 michu staff 12485985 13 mar 2018 file-1 |
| drwxr-xr-x 12 michu staff 384 22 jan 09:50 dir-2 |
| -rwxrwxrwx@ 1 michu staff 193536 21 aoû 19:54 file-2 |
| |
| $> my-ls.sh ./dir-1 ../tp-corbeille/dir-2 file-1 ./file-3 $HOME/tp-corbeille/file-2 |
| ./dir-1 |
| ../tp-corbeille/dir-2 |
| file-1 |
| Erreur : './file-3' introuvable |
| /users/etud/michu/tp-corbeille/file-2 |
| </code> |
| |
---- | ---- |
| |
* Q.3: Copiez ''my-ls.sh'' sous le nom ''my-ls-bis.sh''. Modifiez ''my-ls-bis.sh'' afin que lorsque l'entrée concernée est un dossier, l'ensemble des fichiers qu'il contient soient listés (i.e. leur nom précédé de leur chemins d'accès absolu). Pas de changement lorsque l'entrée concernée est un fichier | ==== Q.4 - Lister des dossiers et des fichiers avec un adressage absolu ==== |
| |
| En partant de la réponse faite à la question précédente, pour l'ensemble de ces paramètres, ''my-ls.sh'' retourne sur la sortie standard une série de lignes. Pour chaque ligne, la sortie désormais sera le paramètre précédé de son adressage absolu. Dans l'hypothèse où l'entrée n'existe pas, un message d'erreur pour cette entrée sera affiché. Un exemple : |
| |
| <code bash> |
| $> pwd |
| /users/etud/michu/tp-corbeille |
| |
| $> ls -l |
| drwxrwxrwx 11 michu staff 352 1 oct 15:58 dir-1 |
| -rwxrwxrwx@ 1 michu staff 12485985 13 mar 2018 file-1 |
| drwxr-xr-x 12 michu staff 384 22 jan 09:50 dir-2 |
| -rwxrwxrwx@ 1 michu staff 193536 21 aoû 19:54 file-2 |
| |
| $> my-ls.sh ./dir-1 ../tp-corbeille/dir-2 file-1 ./file-3 $HOME/tp-corbeille/file-2 |
| /users/etud/michu/tp-corbeille/dir-1 |
| /users/etud/michu/tp-corbeille/dir-2 |
| /users/etud/michu/tp-corbeille/file-1 |
| Erreur : 'file-3' introuvable |
| /users/etud/michu/tp-corbeille/file-2 |
| </code> |
| |
---- | ---- |
| |
* Q.4: A partir des réponses pour les deux précédentes questions, écrivez un script ''recursive-ls.sh'' qui prend en paramètre une ou plusieurs entrées du SGF (fichier ou dossier) et qui liste sur la sortie standard l'ensemble des nom de fichiers précédés de leur chemin absolu présents dans les dossiers ainsi que dans toute la branche résultante (i.e. sous-dossiers, sous-sous-dossiers, etc.) de ce point d'entrée. | ==== Q.5 - Parcours de dossiers ==== |
| |
| Les variables de contexte ''bash'' permettent de récupérer certaines informations : nombre de paramètres, contenu des paramètre, etc. Parmi ces informations se trouvent également la séquence correspondant à la commande exécutée par la ligne de commande ''bash''. Exemple. |
| |
| <code bash> |
| $> pwd |
| /users/etud/michu/tp-corbeille/ |
| |
| $> ls |
| mon-script-exemple.sh dir-1 dir-2 file-1 file-2 |
| |
| $> cat mon-script-exemple.sh |
| #!/bin/bash |
| echo $# |
| echo $1 |
| echo $2 |
| echo $0 |
| |
| $> ./mon-script-exemple.sh dir-1 file-2 |
| 2 |
| dir-1 |
| file-2 |
| ./mon-script-exemple.sh |
| |
| $> ../../michu/tp-corbeille/mon-script-exemple.sh dir-1 file-2 |
| 2 |
| dir-1 |
| file-2 |
| ../../michu/tp-corbeille/mon-script-exemple.sh |
| </code> |
| |
| Proposez un ''bash''-script, nommé ''my-ls-dir.sh'' qui admet un nom de dossier en paramètre et qui renvoie sur la sortie standard l'ensemble de tous les fichiers enracinés à ce dossier (i.e. toute l'arborescence) précédés de leur adressage absolu, à la manière de la question précédente. ** Ce parcours d'arborescence dans le SGF suppose l'adoption d'une démarche récursive **. ''my-ls-dir.sh'' a donc la capacité de s'appeler lui-même. |
| |
---- | ---- |
| |
* Q.5: On souhaite maintenant écrire le script << ''delete-uniq.sh'' >> **qui admet en paramètre un unique nom de fichier** (éventuellement précédé de son adressage dans l'arborescence). Une sortie avec erreur sera générée dans le cas contraire. Ce script aura pour objectif de supprimer l'entrée du SGF et de la transférer dans la corbeille. La procédure de suppression sécurisée sera la suivante: | ==== Q.6 - Finalisation du LS ==== |
- Récupération du nom du fichier à supprimer (on le note **''FILENAME''** par la suite) | |
- Récupération de l'arborescence précédant le nom du fichier à supprimer (on le note **''DIRNAME''** dans la suite de ce processus) | |
- Récupération du numéro d'ordre **''N''** contenu dans ''~/.sh-trashbox/ID'' | |
- Copie et compression par ''gzip'' du fichier à supprimer dans le dossier ''~/.sh-trashbox'' sous le nom **''N.gz''** (remplacer **''N''** par sa valeur bien entendu) | |
- suppression effective de ''FILENAME'' du SGF | |
- calcule de la date de suppression sous la forme d'un nombre de la forme **YearMonthDayHourMinuteSecond** soit **''YYYYMMDDHHMMSS''** | |
- ajout dans ''INDEX'' de la ligne << **''N:FILENAME:DIRNAME:YYYYMMDDHHMMSS''** >> | |
- incrémentation du nombre contenu dans ''~/.sh-trashbox/ID''. On remplace **''N''** par la valeur **''N+1''** | |
| |
Ce processus sera itéré à chaque supression. | A partir des réponses précédentes, écrivez le ''bash''-script ''recursive-ls.sh'' qui prend en paramètre une ou plusieurs entrées du SGF (fichiers et dossiers) et qui liste sur la sortie standard l'ensemble des nom de fichiers précédés de leur chemin absolu présents dans les dossiers ainsi que dans toute la branche résultante (i.e. sous-dossiers, sous-sous-dossiers, etc.) de ce point d'entrée. Exemple. |
| |
| <code bash> |
| $> pwd |
| /users/etud/michu/tp-corbeille/ |
| |
| $> ls |
| mon-script-exemple.sh dir-1 dir-2 file-1 file-2 |
| |
| $> tree |
| . |
| ├── dir-1 |
| │ ├── dir-3 |
| │ │ ├── file-4 |
| │ │ └── file-5 |
| │ └── file-3 |
| ├── dir-2 |
| ├── file-1 |
| ├── file-2 |
| └── mon-script-exemple.sh |
| |
| |
| $> ./recursive-ls.sh dir-1 dir-2 file-1 file-2 file-3 |
| /users/etud/michu/tp-corbeille/dir-1/dir-3/file-4 |
| /users/etud/michu/tp-corbeille/dir-1/dir-3/file-5 |
| /users/etud/michu/tp-corbeille/dir-1/file-3 |
| /users/etud/michu/tp-corbeille/file-1 |
| /users/etud/michu/tp-corbeille/file-2 |
| Erreur : 'file-3' introuvable |
| </code> |
| |
---- | ---- |
| |
* Q.6: Grâce à la question 4, vous disposez d'une commande ''recursive-ls.sh'' qui affiche sur la sortie standard l'ensemble des fichiers présents dans une branche du SGF. En vous basant sur la technique du filtre vus en TD, écrivez la commande qui permet d'afficher sur la sortie standard le nombre de caractères, le nombre de lignes et le nombre de mots pour chacun d'entre eux. (cf. la commande ''wc'') | ==== Q.7 - Effacement d'un fichier ==== |
| |
| On souhaite maintenant écrire le ''bash''-script ''delete-uniq.sh'' **qui admet en paramètre un unique nom de fichier** (éventuellement précédé de son adressage dans l'arborescence). Une sortie avec erreur sera générée dans le cas où le fichier n'existe pas. ''delete-uniq.sh'' a pour objectif de supprimer l'entrée du SGF et de la transférer dans la corbeille. La procédure de suppression sécurisée est la suivante: |
| |
| - Lister le nom fichier à l'aide de ''my-ls.sh'' afin de prendre connaissance de son adressage absolu. |
| - Récupération du nom du fichier à supprimer (on le note **''FILENAME''** par la suite) |
| - Récupération de l'arborescence précédant le nom du fichier à supprimer (on le note **''DIRNAME''** dans la suite de ce processus) |
| - Lecture du numéro d'ordre en cours dans la corbeille **''N''** contenu dans ''~/.sh-trashbox/ID'' |
| - Copie et compression par ''gzip'' du fichier à supprimer dans le dossier ''~/.sh-trashbox'' sous le nom **''N.gz''** (remplacer **''N''** par sa valeur bien entendu) |
| - Suppression effective de ''FILENAME'' du SGF, son nom réel étant forcément ''DIRNAME/FILENAME'' |
| - Calcul de la date de suppression sous la forme d'un nombre de la forme **YearMonthDayHourMinuteSecond** soit **''YYYYMMDDHHMMSS''** (cf. ''man date'') |
| - Ajout dans ''INDEX'' de la ligne << **''N:FILENAME:DIRNAME:YYYYMMDDHHMMSS''** >> |
| - Incrémentation de la valeur contenue dans ''~/.sh-trashbox/ID''. On remplace **''N''** par la valeur **''N+1''** |
| |
| Cette séquence sera réalisée à chaque suppression d'un fichier. |
| |
---- | ---- |
| |
* Q.7: A partir de vos réponses aux questions 5 et 6, vous êtes en mesure d'écrire le script << ''delete-multiple.sh'' >> **qui admet en paramètre un nombre multiple (fichiers ou dossiers) d'entrées** du SGF. Ecrivez << ''delete-multiple.sh'' >>. Vous serez alors en mesure de réaliser des suppressions multiples et récursives. | ==== Q.8 - filtrage ==== |
| |
| Le principe du filtrage, vu en TD vous permet d'agir sur chaque ligne de la sortie standard d'une commande. Une << structure >> générique pour un filtre écrit en ''bash'' peut ainsi être : |
| |
| <code bash> |
| #!/bin/bash |
| while read line |
| do |
| # do something with $line |
| ... |
| # ... and go to next line until stdin is flushed |
| done |
| </code> |
| |
| Une telle structure se traduit de la façon suivante sur la ligne de commande. |
| |
| <code bash> |
| $> cmd |
| a b c d |
| e f |
| g h i j k |
| l |
| |
| $> cmd | while read l |
| > do |
| > echo "ligne : $l" |
| > done |
| ligne : a b c d |
| ligne : e f |
| ligne : g h i j k |
| ligne : l |
| </code> |
| |
| Grâce à votre réponse de la question 6, vous disposez d'une commande ''recursive-ls.sh'' qui affiche sur la sortie standard l'ensemble des fichiers présents dans une branche du SGF. En vous basant sur cette technique du filtrage, écrivez une commande ''my-first-filter.sh'' qui permet affiche sur la sortie standard, pour chacune des entrées (arborescente ou non) le nombre de caractères, le nombre de lignes et le nombre de mots pour chacun d'entre eux. (cf. ''man wc'') |
| |
---- | ---- |
| |
* Q.8: Ecrivez le script << **''list-box.sh''** >> qui affiche l'ensemble des fichiers contenus dans la corbeille ainsi que leur date de suppression. | ==== Q.9 - Vers la corbeille ... ==== |
| |
| A partir de vos réponses aux questions 6, 7 et 8, vous êtes en mesure d'écrire le ''bash''-script ''delete-multiple.sh'' **qui admet en paramètre un nombre multiple (fichiers ou dossiers) d'entrées** du SGF. Ecrivez << ''delete-multiple.sh'' >>. Vous serez alors en mesure de réaliser des suppressions multiples et récursives qui seront transférées vers votre corbeille. |
| |
---- | ---- |
| |
* Q.9: Ecrivez le script << **''restore.sh''** >> qui permet la restauration d'un fichier présent dans la corbeille. A vous d'en définir les modalités. La reconstruction de la branche devra être envisagée le cas échéant. | ==== Q.10 - Lister le contenu de la corbeille ==== |
| |
| Ecrivez le ''bash''-script ''list-box.sh'' qui affiche sur la sortie standard l'ensemble des fichiers contenus dans la corbeille ainsi que leur date de suppression. |
| |
---- | ---- |
| |
* Q.10: Lorsque que vous êtes suffisamment confiant du travail réalisé, vous pouvez, grâce à la commande ''alias'' modifier votre fichier de configuration ''.bashrc'' afin que la commande **''rm''** soit désormais sécurisée. | ==== Q.11 - Restauration de contenu ==== |
| |
| On souhaite écrire le ''bash''-script ''restore.sh''. ''restore.sh'' admet un nombre variable de paramètre correspondant à autant d'entrées de la corbeille que l'on souhaite restaurer. A vous de définir les modalités de fonctionnement de votre paramétrage. A noter que sans autre précision de l'utilisateur, la restauration se fera par défaut dans le dossier originel du fichier. Dans tous les cas, la reconstruction d'une branche pourra être envisagée (cf. option '-p' de la commande ''mkdir''). |
| |
---- | ---- |
| |
| ==== Q.12 - Finalisation du TP - A FAIRE SI VOUS ETES CONFIANT ==== |
| |
| Vous êtes suffisamment confiant du travail réalisé et vous souhaitez désormais faire en sortes que votre gestion de corbeille soit << transparente >> et se substitue à la commande ''rm''. Pour ce faire, les étapes à réaliser sont les suivantes : |
| |
| - Changez dans vos ''bash-script'' la seconde ligne en ''working_directory=$HOME'' ou supprimez toute forme de vérification faite à la question 1. |
| - Dans votre dossier ''.sh-trash'' se trouvent vos ''bash''-script. Déplacez ce dossier à la racine de votre compte. |
| - Editez le fichier de configuration ''.bashrc'' se trouvant à la racine de votre compte. |
| - Ajoutez à la fin de ce fichier la ligne : ''PATH=$PATH:$HOME/.sh-trash'' |
| - Ajoutez à la fin de ce fichier la ligne : ''alias rm='delete-multiple.sh' |
| - redémarrer un terminal ou reconnectez-vous |
| |
| Désormais, chaque frappe de la commande ''rm'' place de façon transparente le fichier effacé dans la corbeille. |
| |
| |
| ---- |