3.3 Leçon 1
Certification : |
Linux Essentials |
---|---|
Version : |
1.6 |
Thème : |
3 La Puissance de la Ligne de Commande |
Objectif : |
3.3 Transformer les Commandes en Script |
Leçon : |
1 sur 2 |
Introduction
Jusqu’à présent, nous avons appris à exécuter des commandes depuis le shell, mais nous pouvons également entrer des commandes dans un fichier, puis configurer ce fichier pour qu’il soit exécutable. Lorsque le fichier est exécuté, ces commandes sont exécutées l’une après l’autre. Ces fichiers exécutables sont appelés scripts, et ils constituent un outil absolument crucial pour tout administrateur système Linux. En gros, on peut considérer que Bash est un langage de programmation aussi bien qu’un shell.
Affichage de la Sortie
Commençons par démontrer une commande que vous avez peut-être déjà vue dans les leçons précédentes : echo
affichera un argument sur la sortie standard.
$ echo "Hello World!" Hello World!
Maintenant, nous allons utiliser la redirection de fichier pour envoyer cette commande à un nouveau fichier appelé new_script
.
$ echo 'echo "Hello World!"' > new_script $ cat new_script echo "Hello World!"
Le fichier new_script
contient maintenant la même commande précédente.
Rendre un Script Exécutable
Montrons quelques-unes des étapes nécessaires pour que ce fichier s’exécute comme nous le souhaitons. La première idée d’un utilisateur pourrait être de simplement taper le nom du script, comme il pourrait taper le nom de n’importe quelle autre commande :
$ new_script /bin/bash: new_script: command not found
Nous supposons sans risque que new_script
existe dans notre emplacement actuel, mais remarquez que le message d’erreur ne nous dit pas que le fichier n’existe pas, il nous dit que la commande n’existe pas. Il serait utile de discuter de la manière dont Linux gère les commandes et les exécutables.
Les Commandes et PATH
Lorsque nous tapons la commande ls
dans le shell, par exemple, nous exécutons un fichier appelé ls
qui existe dans notre système de fichiers. Vous pouvez le prouver en utilisant la commande which
:
$ which ls /bin/ls
Il deviendrait rapidement fastidieux de taper le chemin absolu de ls
chaque fois que l’on souhaite consulter le contenu d’un répertoire, c’est pourquoi Bash dispose d’une variable d’environnement qui contient tous les répertoires où l’on peut trouver les commandes que l’on souhaite exécuter. Vous pouvez consulter le contenu de cette variable en utilisant echo
.
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
Dans chacun de ces emplacements le shell s’attend à trouver la commande, délimitée par des deux-points (:
). Vous remarquerez que /bin
est présent, mais on peut supposer sans risque que notre emplacement actuel ne l’est pas. Le shell cherchera new_script
dans chacun de ces répertoires, mais il ne le trouvera pas et enverra donc l’erreur que nous avons vue ci-dessus.
Il y a trois solutions à ce problème : nous pouvons déplacer new_script
dans l’un des répertoires de PATH
, nous pouvons ajouter notre répertoire actuel à PATH
, ou nous pouvons changer la façon dont nous essayons d’appeler le script. Cette dernière solution est la plus simple, elle nous oblige simplement à spécifier l’emplacement actuel lors de l’appel du script en utilisant un point suivi de la barre oblique (./
).
$ ./new_script /bin/bash: ./new_script: Permission denied
Le message d’erreur a changé, ce qui indique que nous avons fait quelques progrès.
Permission d’Exécution
La première investigation qu’un utilisateur doit faire dans ce cas est d’utiliser ls -l
pour examiner le fichier :
$ ls -l new_script -rw-rw-r-- 1 user user 20 Apr 30 12:12 new_script
Nous pouvons voir que les autorisations pour ce fichier sont fixées à 664 par défaut. Nous n’avons pas encore défini les permissions d’exécution pour ce fichier.
$ chmod +x new_script $ ls -l new_script -rwxrwxr-x 1 user user 20 Apr 30 12:12 new_script
Cette commande a donné des autorisations d’exécution à tous les utilisateurs. Sachez que cela peut constituer un risque pour la sécurité, mais pour l’instant, il s’agit d’un niveau de permission acceptable.
$ ./new_script Hello World!
Nous sommes maintenant en mesure d’exécuter notre script.
Définir l’Interprète
Comme nous l’avons démontré, nous avons pu simplement entrer du texte dans un fichier, le définir comme un exécutable et l’exécuter. new_script
est fonctionnellement toujours un fichier texte normal, mais nous avons réussi à le faire interpréter par Bash. Mais qu’en est-il s’il est écrit en Perl, ou en Python ?
C’est une très bonne pratique de spécifier le type d’interprète que nous voulons utiliser dans la première ligne d’un script. Cette ligne est appelée une ligne bang ou plus communément un shebang. Elle indique au système comment nous voulons que ce fichier soit exécuté. Puisque nous apprenons le Bash, nous utiliserons le chemin absolu de notre exécutable Bash, en utilisant encore une fois which
:
$ which bash /bin/bash
Notre shebang commence par un dièse et un point d’exclamation, suivi du chemin absolu ci-dessus. Ouvrons new_script
dans un éditeur de texte et insérons le shebang. Profitons également de l’occasion pour insérer un commentaire dans notre script. Les commentaires sont ignorés par l’interprète. Ils sont écrits pour le bénéfice des autres utilisateurs qui souhaitent comprendre votre script.
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de documenter tous les scripts. echo "Hello World!"
Nous allons également apporter une modification supplémentaire au nom du fichier : nous allons enregistrer ce fichier sous le nom new_script.sh
. Le suffixe ".sh" ne modifie en rien l’exécution du fichier. Par convention, les scripts bash prennent l’extension .sh
ou .bash
afin de les identifier plus facilement, de la même manière que les scripts Python sont généralement identifiés avec le suffixe .py
.
Les Éditeurs de Textes Populaires
Les utilisateurs de Linux doivent souvent travailler dans un environnement où les éditeurs de texte graphiques ne sont pas disponibles. Il est donc fortement recommandé de se familiariser au moins un peu avec l’édition de fichiers texte à partir de la ligne de commande. Deux des éditeurs de texte les plus courants sont vi
et nano
.
vi
vi
est un éditeur de texte vénérable et est installé par défaut sur presque tous les systèmes Linux existants. vi
a donné naissance à un clone appelé vi IMproved ou vim
qui ajoute certaines fonctionnalités mais maintient l’interface de vi
. Bien que travailler avec vi
soit intimidant pour un nouvel utilisateur, l’éditeur est populaire et très apprécié des utilisateurs qui apprennent ses nombreuses fonctionnalités.
La différence la plus importante entre vi
et les applications telles que Notepad est que vi
a trois modes différents. Au démarrage, les touches H, J, K et L sont utilisées pour naviguer, et non pour taper. Dans ce mode navigation, vous pouvez appuyer sur I pour entrer en mode insertion. À ce stade, vous pouvez taper normalement. Pour quitter le mode insertion, vous appuyez sur Echap pour revenir au mode navigation. Dans le mode navigation, vous pouvez appuyer sur : pour entrer en mode commande. A partir de ce mode, vous pouvez sauvegarder, supprimer, quitter ou modifier des options.
Bien que vi
ait une longue courbe d’apprentissage, les différents modes peuvent, avec le temps, permettre à un utilisateur expérimenté de devenir plus efficace qu’avec d’autres éditeurs.
nano
nano
est un outil plus récent, conçu pour être simple et plus facile à utiliser que vi
. nano
n’a pas de modes différents. Au lieu de cela, un utilisateur au démarrage peut commencer à taper, et utiliser la touche Ctrl pour accéder aux outils affichés au bas de l’écran.
[ Welcome to nano. For basic help, type Ctrl+G. ] ^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos M-U Undo ^X Exit ^R Read File ^\ Replace ^U Uncut Text ^T To Spell ^_ Go To Line M-E Redo
Les éditeurs de texte sont une question de préférence personnelle, et l’éditeur que vous choisissez d’utiliser n’aura aucune incidence sur cette leçon. Mais se familiariser avec un ou plusieurs éditeurs de texte sera payant à l’avenir.
Les Variables
Les variables sont une partie importante de tout langage de programmation, et Bash n’est pas différent. Lorsque vous démarrez une nouvelle session à partir du terminal, le shell définit déjà certaines variables pour vous. La variable PATH
en est un exemple. Nous les appelons variables d’environnement, car elles définissent généralement les caractéristiques de l’environnement de notre shell. Vous pouvez modifier et ajouter des variables d’environnement, mais pour l’instant, concentrons-nous sur la définition des variables à l’intérieur de notre script.
Nous allons modifier notre script pour qu’il ressemble à ceci :
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username=Carol echo "Hello $username!"
Dans ce cas, nous avons créé une variable appelée username
et nous lui avons attribué la valeur Carol
. Veuillez noter qu’il n’y a pas d’espace entre le nom de la variable, le signe égal, et la valeur attribuée.
Dans la ligne suivante, nous avons utilisé la commande echo
avec la variable, mais il y a un signe de dollar ($
) devant le nom de la variable. C’est important, car il indique au shell que nous souhaitons traiter username
comme une variable, et pas seulement comme un mot normal. En entrant $username
dans notre commande, nous indiquons que nous voulons effectuer une substitution, en remplaçant le nom d’une variable par la valeur attribuée à cette variable.
En exécutant le nouveau script, nous obtenons cette sortie :
$ ./new_script.sh Hello Carol!
-
Les variables ne doivent contenir que des caractères alphanumériques ou des traits de soulignement (underscores), et sont sensibles à la casse.
Username
etusername
seront traitées comme des variables distinctes. -
La substitution de variable peut également avoir le format
${username}
, avec l’ajout des{ }
. Ceci est également acceptable. -
Les variables en Bash ont un type implicite, et sont considérées comme des chaînes de caractères. Cela signifie que l’exécution de fonctions mathématiques en Bash est plus compliquée que dans d’autres langages de programmation tels que C/C++ :
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username=Carol x=2 y=4 z=$x+$y echo "Hello $username!" echo "$x + $y" echo "$z"
$ ./new_script.sh Hello Carol! 2 + 4 2+4
L’Utilisation des Guillemets avec des Variables
Modifions comme suit la valeur de notre variable username
:
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username=Carol Smith echo "Hello $username!"
L’exécution de ce script nous donnera une erreur :
$ ./new_script.sh ./new_script.sh: line 5: Smith: command not found Hello !
Gardez à l’esprit que Bash est un interprète et qu’en tant que tel, il interprète notre script ligne par ligne. Dans ce cas, il interprète correctement username=Carol
pour définir une variable username
avec la valeur Carol
. Mais il interprète ensuite l’espace comme indiquant la fin de cette tâche, et Smith
comme étant le nom d’une commande. Pour que l’espace et le nom Smith
soient inclus comme nouvelle valeur de notre variable, nous mettrons des guillemets doubles ("
) autour du nom.
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username="Carol Smith" echo "Hello $username!"
$ ./new_script.sh Hello Carol Smith!
Une chose importante à noter dans Bash est que les guillemets doubles et les guillemets simples ('
) se comportent très différemment. Les guillemets doubles sont considérés comme “faibles”, car ils permettent à l’interprète d’effectuer des substitutions à l’intérieur des guillemets. Les guillemets simples sont considérés comme “forts”, parce qu’ils empêchent toute substitution de se produire. Prenons l’exemple suivant :
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username="Carol Smith" echo "Hello $username!" echo 'Hello $username!'
$ ./new_script.sh Hello Carol Smith! Hello $username!
Dans la deuxième commande echo
, l’interprète a été empêché de remplacer $username
par Carol Smith
, et la sortie est donc prise littéralement.
Les Arguments
Vous êtes déjà familiarisé avec l’utilisation d’arguments dans les utilitaires de base de Linux. Par exemple, rm fichiertest
contient à la fois l’exécutable rm
et un argument fichiertest
. Les arguments peuvent être passés au script lors de l’exécution, et modifieront le comportement du script. Ils sont faciles à mettre en œuvre.
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username=$1 echo "Hello $username!"
Au lieu d’attribuer une valeur à username
directement à l’intérieur du script, nous lui attribuons la valeur d’une nouvelle variable $1
, qui correspond à la valeur du premier argument.
$ ./new_script.sh Carol Hello Carol!
Les neuf premiers arguments sont traités de cette manière. Il existe des moyens de traiter plus de neuf arguments, mais cela dépasse le cadre de cette leçon. Nous allons montrer un exemple en utilisant seulement deux arguments :
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username1=$1 username2=$2 echo "Hello $username1 and $username2!"
$ ./new_script.sh Carol Dave Hello Carol and Dave!
Il y a une considération importante à prendre en compte lorsque l’on utilise des arguments : Dans l’exemple ci-dessus, il y a deux arguments, Carol
et Dave
, attribués respectivement à $1
et $2
. Si le deuxième argument est manquant, par exemple, le shell ne produira pas d’erreur. La valeur de $2
sera simplement null, ou rien du tout.
$ ./new_script.sh Carol Hello Carol and !
Dans notre cas, il serait bon d’introduire une certaine logique dans notre script afin que différentes conditions affectent la sortie que nous souhaitons afficher. Nous commencerons par introduire une autre variable utile, puis nous passerons à la création des déclarations if.
Retourner le Nombre d’Arguments
Alors que des variables telles que $1
et $2
contiennent la valeur des arguments de position, une autre variable $#
contient le nombre d’arguments.
#!/bin/bash # C'est notre premier commentaire. C'est aussi une bonne pratique de commenter tous les scripts. username=$1 echo "Hello $username!" echo "Number of arguments: $#."
$ ./new_script.sh Carol Dave Hello Carol! Number of arguments: 2.
La Logique Conditionnelle
L’utilisation de la logique conditionnelle dans la programmation est un vaste sujet, qui ne sera pas traité en profondeur dans cette leçon. Nous nous concentrerons sur la syntaxe des conditions en Bash, qui diffère de la plupart des autres langages de programmation.
Commençons par passer en revue ce que nous espérons réaliser. Nous disposons d’un script simple qui devrait afficher un message de salutation à un seul utilisateur. S’il y a autre chose qu’un seul utilisateur, nous devrions afficher un message d’erreur.
-
La condition que nous testons est le nombre d’utilisateurs, qui est contenu dans la variable
$#
. Nous aimerions savoir si la valeur de$#
est1
. -
Si la condition est vraie, l’action que nous ferons sera de saluer l’utilisateur.
-
Si la condition est fausse, nous affichons un message d’erreur.
Maintenant que la logique est claire, nous allons nous concentrer sur la syntaxe requise pour mettre en œuvre cette logique.
#!/bin/bash # Un script simple pour saluer un seul utilisateur. if [ $# -eq 1 ] then username=$1 echo "Hello $username!" else echo "Veuillez ne saisir qu'un seul argument." fi echo "Nombre d'arguments : $#."
La logique conditionnelle est contenue entre if
et fi
. La condition à tester est située entre crochets [ ]
, et la mesure à prendre si la condition est vraie est indiquée après then
. Notez les espaces entre les crochets et la logique contenue. L’omission de cet espace entraînera des erreurs.
Ce script produira soit notre message d’accueil, soit le message d’erreur. Mais il affichera toujours la ligne Nombre d’arguments
.
$ ./new_script.sh Veuillez ne saisir qu'un seul argument. Nombre d'arguments : 0. $ ./new_script.sh Carol Hello Carol! Nombre d'arguments : 1.
Remarquer la déclaration if
. Nous avons utilisé -eq
pour faire une comparaison numérique. Dans ce cas, nous vérifions que la valeur de $#
est égale à un. Les autres comparaisons que nous pouvons effectuer sont :
-ne
-
Différent de
-gt
-
Supérieur à
-ge
-
Supérieur ou égal à
-lt
-
Inférieur à
-le
-
Inférieur ou égal à
Exercices Guidés
-
L’utilisateur tape ce qui suit dans son shell :
$ PATH=~/scripts $ ls Command 'ls' is available in '/bin/ls' The command could not be located because '/bin' is not included in the PATH environment variable. ls: command not found
-
Qu’a fait l’utilisateur ?
-
Quelle commande permettra de combiner la valeur actuelle de
PATH
avec le nouveau répertoire~/scripts
?
-
-
Considérez le script suivant. Remarquez qu’il utilise
elif
pour vérifier une deuxième condition :> /!bin/bash > fruit1 = Pommes > fruit2 = Oranges if [ $1 -lt $# ] then echo "C'est comme comparer $fruit1 et $fruit2 " > elif [$1 -gt $2 ] then > echo '$fruit1 gagne !' else > echo "Fruit2 gagne !" > done
-
Les lignes marquées d’un
>
contiennent des erreurs. Corrigez les erreurs.
-
-
Quel sera le résultat dans les situations suivantes ?
$ ./guided1.sh 3 0
$ ./guided1.sh 2 4
$ ./guided1.sh 0 1
Exercices d’Exploration
-
Rédigez un script simple qui vérifiera si deux arguments exactement sont passés. Si c’est le cas, affichez les arguments dans l’ordre inverse. Prenons cet exemple (remarque : votre code peut être différent de celui-ci, mais il doit aboutir au même résultat) :
if [ $1 == $number ] then echo "Vrai!" fi
-
Ce code est correct, mais il ne s’agit pas d’une comparaison de chiffres. Recherchez sur Internet pour découvrir en quoi ce code est différent de l’utilisation de
-eq
. -
Une variable d’environnement permet d’afficher le répertoire courant. Utilisez
env
pour découvrir le nom de cette variable. -
En utilisant ce que vous avez appris dans les questions 2 et 3, écrivez un court script qui accepte un argument. Si un argument est passé, vérifiez si cet argument correspond au nom du répertoire courant. Si c’est le cas, affichez
oui
. Sinon, afficheznon
.
Résumé
Dans cette section, vous avez appris :
-
Comment créer et exécuter des scripts simples
-
Comment utiliser un shebang pour spécifier un interprète
-
Comment définir et utiliser les variables dans les scripts
-
Comment gérer les arguments dans les scripts
-
Comment construire des déclarations de
if
-
Comment comparer des nombres à l’aide d’opérateurs numériques
Commandes utilisées dans les exercices :
echo
-
Affiche une chaîne de caractères sur la sortie standard.
env
-
Affiche toutes les variables d’environnement sur la sortie standard.
which
-
Affiche le chemin absolu d’une commande.
chmod
-
Modifie les autorisations d’un fichier.
Variables spéciales utilisées dans les exercices :
$1, $2, … $9
-
Contient des arguments positionnels transmis au script.
$#
-
Contient le nombre d’arguments passés au script.
$PATH
-
Contient les répertoires qui contiennent les exécutables utilisés par le système.
Opérateurs utilisés dans les exercices :
-ne
-
Différent de
-gt
-
Supérieur à
-ge
-
Supérieur ou égal à
-lt
-
Inférieur à
-le
-
Inférieur ou égal à
Réponses aux Exercices Guidés
-
L’utilisateur tape dans son shell ce qui suit :
$ PATH=~/scripts $ ls Command 'ls' is available in '/bin/ls' The command could not be located because '/bin' is not included in the PATH environment variable. ls: command not found
-
Qu’a fait l’utilisateur ?
L’utilisateur a écrasé le contenu de PATH avec le répertoire
~/scripts
. La commandels
ne peut plus être trouvée, car elle n’est pas contenue dans PATH. Notez que ce changement n’affecte que la session en cours, en se déconnectant et en se reconnectant les changements seront annulés. -
Quelle commande permettra de combiner la valeur actuelle de
PATH
avec le nouveau répertoire~/scripts
?PATH=$PATH:~/scripts
-
-
Considérez le script suivant. Remarquez qu’il utilise
elif
pour vérifier une deuxième condition :> /!bin/bash > fruit1 = Pommes > fruit2 = Oranges if [ $1 -lt $# ] then echo "C'est comme comparer $fruit1 et $fruit2 !" > elif [$1 -gt $2 ] then > echo '$fruit1 gagne !' else > echo "Fruit2 gagne!" > done
-
Les lignes marquées d’un
>
contiennent des erreurs. Corrigez les erreurs.#!/bin/bash fruit1=Pommes fruit2=Oranges if [ $1 -lt $# ] then echo "C'est comme comparer $fruit1 et $fruit2 !" elif [ $1 -gt $2 ] then echo "$fruit1 gagne !" else echo "$fruit2 gagne !" fi
-
-
Quel sera le résultat dans les situations suivantes ?
$ ./guided1.sh 3 0
Pommes gagne !
$ ./guided1.sh 2 4
Oranges gagne !
$ ./guided1.sh 0 1
C’est comme comparer Pommes et Oranges!
Réponses aux Exercices d’Exploration
-
Rédigez un script simple qui vérifiera si deux arguments exactement sont passés. Si c’est le cas, affichez les arguments dans l’ordre inverse. Prenons cet exemple (remarque : votre code peut être différent de celui-ci, mais il doit aboutir au même résultat) :
if [ $1 == $number ] then echo "True!" fi
#!/bin/bash if [ $# -ne 2 ] then echo "Erreur" else echo "$2 $1" fi
-
Ce code est correct, mais il ne s’agit pas d’une comparaison de chiffres. Recherchez sur Internet pour découvrir en quoi ce code est différent de l’utilisation de
-eq
.L’utilisation de
==
permettra de comparer les chaînes de caractères. C’est-à-dire que si les caractères des deux variables correspondent exactement, alors la condition est vraie.abc == abc
vraie
abc == ABC
faux
1 == 1
vraie
1+1 == 2
faux
Les comparaisons de chaînes entraînent un comportement inattendu si vous faites des tests de chiffres.
-
Une variable d’environnement permet d’afficher le répertoire courant. Utilisez
env
pour découvrir le nom de cette variable.PWD
-
En utilisant ce que vous avez appris dans les questions 2 et 3, écrivez un court script qui accepte un argument. Si un argument est passé, vérifiez si cet argument correspond au nom du répertoire courant. Si c’est le cas, affichez
oui
. Sinon, afficheznon
.#!/bin/bash if [ "$1" == "$PWD" ] then echo "oui" else echo "non" fi