L'automatisation des tâches fait référence à la délégation/décharge des actions de l'utilisateur aux programmes du système informatique. Un programme effectuera automatiquement, de lui-même, des actions que l'utilisateur ferait, ce qui lui fera gagner du temps.
Les actions candidates à l'automatisation sont généralement des actions répétitives, peu simples et non interactives. Leur automatisation libérera l'utilisateur de leur exécution manuelle, répétitive et fastidieuse.
Commande | Brève description |
---|---|
cat | comment afficher le contenu du fichier |
seq | génère une séquence de nombres |
grep | extrait les lignes contenant une expression régulière spécifique |
cut | extraire certaines colonnes |
sed | filtre de texte avancé utilisé pour les substitutions |
wc | compter le nombre de lignes, de mots ou de caractères |
head | afficher les premières lignes ou caractères |
tail | afficher les dernières lignes ou caractères |
for | parcourir la liste des éléments pour appliquer des commandes à chaque élément |
if | condition d'exécution de certaines commandes |
$(comm) | expansion d'une commande (extension de commande) - remplacement par la sortie de la commande |
comm1 | comm2 | reliant deux commandes : la sortie de la première commande devient l'entrée de la deuxième commande |
$var ou ${var} | la valeur de la variable var |
${#var} | longueur de la valeur de la variable var (en caractères) |
${var:2:3} | une sous-chaîne de la valeur de la variable var : 3 caractères sont extraits de l'index 2 |
La création de scripts implique l'utilisation d'un langage interprété (appelé langage de script). Cela peut être un langage comme Python, Perl ou Ruby, ou même le shell CLI (interpréteur de commandes). Les langages de script ont l'avantage de se développer rapidement : nous ajoutons et testons rapidement de nouvelles fonctionnalités.
Les scripts shell ont l'avantage d'utiliser les commandes shell existantes (commandes de fichiers, commandes de processus, commandes de filtrage de texte). Pour les actions rapides (quick'n'dirty), les scripts shell sont une très bonne solution. Lorsque l'on a des manipulations numériques ou des manipulations de chaînes, les scripts shell peuvent être insuffisants et il est conseillé de se tourner vers un langage de script plus complet, comme Python, Ruby ou Perl.
Les fonctionnalités du shell sont utilisées dans l'efficacité et l'automatisation de l'exécution des commandes. Je les ai utilisés et je m'en suis souvenu lors des derniers laboratoires, en particulier le dernier laboratoire. Ces fonctionnalités sont :
>
, <
, »
| (pipe)
Tout au long de ce TP, nous utiliserons des fonctionnalités shell spécifiquement utilisées dans les scripts shell :
if
, for
, while
L'automatisation via les scripts shell implique généralement une séquence de commandes. Ces commandes sont ajoutées à un script où elles seront exécutées ensemble, sans qu'il soit nécessaire d'exécuter manuellement chaque commande.
Pour configurer l'exécution d'une séquence de commandes, nous pouvons conditionner l'exécution du script à l'aide de variables ou d'arguments dans la ligne de commande. Ceux-ci peuvent générer un comportement de script différent en fonction de leurs valeurs.
En fonction de variables, d'arguments de ligne de commande ou de données d'entrée, un script peut prendre des décisions conditionnelles. La vérification d'une condition peut conduire à un comportement ou à un autre.
Lors de l'exécution d'un script, nous voudrons souvent qu'une action cible plusieurs fichiers, processus ou chaînes. Pour cela, nous verrons comment utiliser des boucles pour parcourir des listes d'éléments.
Les commandes utilisées peuvent recevoir en argument ou en entrée standard la sortie d'autres commandes. Dans les scripts shell, nous utilisons des fonctionnalités de chaînage de commandes telles que l'expansion de commandes ou des pipes conduisant à des résultats plus complexes.
Dans le répertoire du référentiel du laboratoire, il y a un fichier Students.txt que nous utiliserons comme support pour les commandes d'expressions régulières. Ce fichier contient une liste d'étudiants avec le nom complet des étudiants (première colonne), leur groupe (deuxième colonne) et diverses notes USO (note finale - troisième colonne, note du test de la grille - quatrième colonne - et note du test pratique - cinquième colonne), champs séparés par le caractère de tabulation.
Pour rechercher et sélectionner des lignes dans des fichiers texte, nous utilisons la commande grep, qui à son tour utilise des expressions régulières. Ainsi, si nous voulons sélectionner les étudiants qui ont la lettre z dans leur nom, nous utilisons la commande
student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ grep 'z' students.txt GHECENCO F. Răzvan 312CC 8 8.75 4.67 MARIN N. Răzvan 312CC 5 3.5 4.2
grep
soit entouré de guillemets simples (') pour être échappé. De cette façon, les caractères de l'expression régulière seront transmis exactement à la commande grep et ne seront pas interprétés par le shell.
Ainsi, la commande grep pour extraire les étudiants dont le nom commence par la lettre F est
student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ grep '[ -]F[a-z]\+[^\.]' students.txt ONEA I. Flavia-Katilina 311CC 7 6.5 4.33 EPURE P. Andi-Florin 314CC 8 9.5 3.67 NEACȘU C. Florin-Mărgărit 314CC 10 9 9 COSTEA I. Florin Traian 315CC 4 3.5 3.7 CHIȚESCU E. Bogdan-Florentin 315CC 9 7.75 6.89
L'utilitaire tr
permet la traduction, la suppression et la manipulation des caractères reçus en entrée. Fondamentalement, sed
est un éditeur de flux qui peut effectuer des transformations au niveau de la chaîne sur un texte reçu en entrée. De plus, sed peut accepter des expressions régulières comme argument de recherche.
Par exemple, en utilisant à la fois tr et sed, remplaçons le caractère ',' par TAB dans student.csv :
student@ubuntu:~/uso-lab/labs/06-scripting/support/00-basics$ cat students.csv | tr , "\t" > students.out student@ubuntu:~/uso-lab/labs/06-scripting/support/00-basics$ cat students.out VLĂDUȚU I. Liviu-Alexandru 311CC 6 3.5 5.22 GEORGIU V. Alexandra-Maria 311CC 10 10 9.67 PĂUNOIU N. Gabriel 311CC 7 6.5 3.5 BĂCÎRCEA A. Andrei 311CC 7 5.5 4.44 [...] student@ubuntu:~/uso-lab/labs/06-scripting/support/00-basics$ sed 's/,/\t/g' students.csv > students.out student@ubuntu:~/uso-lab/labs/06-scripting/support/00-basics$ cat students.out VLĂDUȚU I. Liviu-Alexandru 311CC 6 3.5 5.22 GEORGIU V. Alexandra-Maria 311CC 10 10 9.67 PĂUNOIU N. Gabriel 311CC 7 6.5 3.5 BĂCÎRCEA A. Andrei 311CC 7 5.5 4.44 [...]
Nous pouvons extraire des informations structurées sur les lignes et les colonnes à l'aide de l'utilitaire cut
:
student@ubuntu:~/uso-lab/labs/06-scripting/support/00-basics$ cat /etc/passwd | cut -d':' -f1,6 | head -3 root:/root daemon:/usr/sbin bin:/bin
Si nous voulons trier les élèves du fichier dans l'ordre de leurs noms, nous utiliserons la commande sort
:
student@uso:~/uso-lab/labs/06-scripting/00-basics$ sort students.csv ALECU C. Ionuț-Gabriel,312CC,7,4.5,6.4 ASĂVOAEI P. Cătălin,315CC,8,6.75,7 BĂCÎRCEA A. Andrei,311CC,7,5.5,4.44 BADEA P. Bogdan,314CC,4,2.75,1.56 [...]
Certaines options souvent utilisées avec sort sont :
-t
spécifie le séparateur-k
spécifie l'index, ou la clé, de la colonne par laquelle nous voulons trier les entréesn
tri numérique (la valeur par défaut est alphabétique)-r
tri inversé (ascendant par défaut)Nous voulons faire un tri numérique décroissant par année, suivi d'un tri alphabétique par groupe (c'est-à-dire toutes les années commençant par 10 mais triées par ordre de groupe). Ainsi, pour trier les entrées dans l'ordre des notes, nous utiliserons le séparateur , (virgule, virgule) et la 3ème colonne pour la clé :
student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ sort -t ',' -k 3,3nr -k 2,2 students.csv GEORGIU V. Alexandra-Maria,311CC,10,10,9.67 MUȘATESCU V. Alexandru-Petrișor,311CC,10,8.5,9 RADU L. Alina,311CC,10,10,7.89 GONDOȘ I. Gabriel,312CC,10,9,7.33 [...]
S'il y a des lignes en double, nous pouvons utiliser l'utilitaire uniq en conjonction avec sort pour les supprimer. Pour cela, nous ajoutons une ligne dupliquée dans Students.csv :
student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ sort -t ',' -k 3,3nr -k 2,2 students.csv | wc -l 93 student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ sort -t ',' -k 3,3nr -k 2,2 students.csv | uniq | wc -l 92 student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ uniq students.csv | wc -l 93
Un script shell est un fichier texte qui contient des commandes et des constructions spécifiques au shell. Un script shell commence par la construction #!/bin/bash
, appelée un shebang qui indique l'interpréteur du script ; dans ce cas, l'interpréteur est le shell Bash lui-même. Si aucun shell n'est spécifié via shebang, le shell par défaut (défini dans /etc/passwd
) attribué à l'utilisateur connecté sera pris par défaut.
Par exemple, les one-liners que j'ai écrits jusqu'à présent pourraient être mis dans un script shell et, de plus, s'il s'agit de longues commandes et qu'elles ne tiennent pas sur une seule ligne, nous pouvons les “casser” en plusieurs lignes en utilisant le séparateur \
:
#!/bin/bash export DATE=$(date +20%y%m%d) && \ mkdir -p /usr/share/snapshots && \ tar -cvpzf /usr/share/snapshots/$HOSTNAME_$DATE.tar.gz \ --exclude=/proc --exclude=/lost+found \ --exclude=/sys --exclude=/mnt \ --exclude=/media --exclude=/dev \ --exclude=/share/Archive /
\
il ne doit plus y avoir de caractères (pas même d'espaces à la fin)
Le script contient des commandes courantes utilisées dans le shell et d'autres commandes que l'on trouve plus souvent dans les scripts : while, if, for
. Ce ne sont pas des instructions, ce sont toujours des commandes shell ; peut également être utilisé, si la syntaxe est correcte, sur la ligne de commande.
Un script hérite des variables d'environnement du shell parent telles que HOME, BASH, IFS, USER. Dans le script, nous pouvons les utiliser comme ceci :
#!/bin/bash echo $HOME
En plus de ces variables, le script peut recevoir un certain nombre d'arguments de ligne de commande. En utilisant les variables suivantes, nous pouvons faire référence aux arguments reçus par le script depuis la ligne de commande :
$*
est une chaîne ($1, $2 … @ est une liste d'arguments de script
*
$1, $2 … 0 est le nom du script
*
# arguments to $0: $*echo first argument: 2 echo third argument: @ </code>
student@uso:~$ ./arguments.sh banane cirese caise castraveti There are 4 arguments to arguments.sh: banane cirese caise castraveti first argument: banane second argument: cirese third argument: caise the list of arguments: banane cirese caise castraveti
Créez un nouveau script extract-name avec le contenu suivant :
#!/bin/bash IFS=',' while read name group final_grade test_grade practical_grade; do echo "$name" done < students.csv
Pour l'analyse dans le shell, nous utilisons la construction while read …
. La construction est suivie des noms des variables dans lesquelles nous retiendrons les champs analysés à l'intérieur de chaque ligne. Nous utilisons le fichier Students.csv
dans le répertoire parent comme entrée ; est un fichier au format CSV (Comma Separated Values) utilisant le caractère virgule (,, virgule) comme séparateur. Pour extraire uniquement les noms des étudiants du fichier d'entrée, nous allons exécuter le script extract-name
:
student@uso:~/uso-lab/labs/06-scripting/support/00-basics$ ./extract-name VLĂDUȚU I. Liviu-Alexandru GEORGIU V. Alexandra-Maria PĂUNOIU N. Gabriel BĂCÎRCEA A. Andrei [...]
Étant donné que le format d'entrée utilise une virgule (,, virgule) comme séparateur, nous avons défini la variable interne IFS (Internal Field Separator) dans le script à la valeur ',', comme nous le voyons à la ligne 3 du script extract-name :
IFS=','
Nous pouvons étendre le script ci-dessus pour afficher uniquement les étudiants dont la moyenne est supérieure à 5.
#!/bin/bash IFS=',' while read name group final_grade test_grade practical_grade; do if test "$final_grade" -gt 5; then echo "$name,$group,$final_grade" fi done < students.csv
Il existe également des constructions de type for
dans bash. Un exemple courant consiste à parcourir le contenu d'un répertoire et à effectuer des opérations sur les fichiers. Par exemple, nous souhaitons sauvegarder tous les fichiers d'un répertoire envoyé en paramètre au script :
#!/bin/bash for file in $1/* do if test -f $file; then stat --print="%a %F %n\n" $file cp $file $file.bkp fi done
#!/bin/bash for file in $(find /usr/share/pixmaps/ -type f -iname '*.jpg') do echo $file done
Dans cet ensemble d'exercices/tutoriels, nous verrons comment utiliser les alias pour rendre les actions plus efficaces.
Commençons par utiliser la commande xdg-open dans les formulaires ci-dessous :
xdg-open . xdg-open http://google.com <code> Ces commandes ouvrent respectivement un navigateur de fichiers, un navigateur web. Pour effectuer des actions plus rapidement, nous utilisons un alias. Nous créons des alias open et go pour xdg-open comme ci-dessous : <code bash> alias open='xdg-open' alias go='xdg-open'
Exercice : Utilisez maintenant la commande open ou la commande go pour les deux actions ci-dessus. Nous avons simplifié la commande xdg-open (plus difficile à écrire et plus difficile à retenir).
Saisissez le sous-répertoire noms-indexés/. Nous voulons effectuer des opérations automatiques sur le système de fichiers, en utilisant les lignes for et one.
Nous exécutons les deux commandes ci-dessous :
for i in $(seq -f "%02g" 1 3); do touch test-"$i".txt; done for i in $(seq -f "%02g" 0 12); do mkdir uso-curs-"$i"; done
A la fin de l'exécution de ces commandes, on obtient 3 fichiers texte (pour les 3 papiers/tests) et 13 répertoires, pour les 13 répertoires. J'ai utilisé for pour parcourir une liste et seq pour créer une liste numérique.
Exercice : Créez une doublure qui crée les 13 répertoires et crée dans chaque répertoire un sous-répertoire appelé slides/, un fichier appelé notes.txt et un fichier appelé resources.txt.
Nous exécutons les commandes suivantes pour générer un mot de passe à 16 caractères et afficher les PID des processus utilisateur étudiants :
tr -dc 'a-zA-Z0-9~!@#$%^&*_()+}{?></";.,[]=-' < /dev/urandom | fold -w 32 | head -n 1 ps -ef | grep student | tr -s ' ' | cut -d ' ' -f 2
Exercice : Pour désactiver le montage des clés USB sur le système, nous pouvons utiliser les commandes :
sudo rmmod uas sudo rmmod usb_storage
Ensuite, pour réactiver, on utilise les commandes :
sudo modprobe usb_storage sudo modprobe uas
Créez des scripts disable-usb et enable-usb pour désactiver et activer le montage de la clé USB, respectivement. Exécutez-les pour vérification.
Exercice : Créez un script appelé system-info qui affiche les informations système dans le modèle ci-dessous :
date: 2019-11-05 kernel: 5.0.0-32-generic version: Ubuntu 18.04.3 LTS num_processes: 336