Programmation Bash/Version imprimable
Une version à jour et éditable de ce livre est disponible sur Wikilivres,
une bibliothèque de livres pédagogiques, à l'URL :
https://fr.wikibooks.org/wiki/Programmation_Bash
Introduction
Le Bash est un shell, c'est-à-dire un interpréteur de commandes, écrit pour le projet GNU en 1989.
Bash est l'acronyme de Bourne-Again SHell, un calembour sur le shell Bourne sh, qui a été historiquement le premier shell d'Unix. Le shell Bourne original fut écrit par Stephen Bourne. Bash a été principalement écrit par Brian Fox et Chet Ramey. La syntaxe de Bash est compatible avec sh et inclut des développements issus de csh et ksh.
En effet, le Korn shell (ksh) est un shell Unix développé par David Korn. Il est compatible avec le Bash et inclut également un grand nombre de fonctionnalités du C shell, mais il permet également des fonctions de scripting avancées utilisées dans des langages de programmation plus évolués comme awk, sed, et Perl. La liste de ses commandes sera détaillée à la fin de ce livre.
Bash est le shell par défaut de la plupart des systèmes GNU/Linux, il est distribué sous la licence libre GNU GPL. Il fonctionne sur la plupart des systèmes d'exploitation de type Unix, et a également été porté sous Windows par Cygwin, puis sous windows 10 build 14316 par Microsoft.
Si un langage de programmation permet de dire à un processeur ce qu’il doit faire, un interpréteur de commandes permet de dire à un système d’exploitation, un service ou à une application ce qu’ils doivent faire. Cette nuance permet aux anglo-saxons de distinguer les notions de programming lorsqu’il s’agit d’écrire un code pour créer une application et de scripting lorsqu’il s’agit de programmer un système d’exploitation, un service ou une application. Le jeu d'instructions de Bash est donc spécialisé afin d'utiliser des systèmes Unix.
Hello World
Pour créer une variable :
# Bash est un langage de script système.
# Il n'est pas utilisé pour faire des applications graphiques.
# Lorsqu'on veut afficher quelque chose, c'est dans le terminal que le texte sera affiché.
# La commande permettant d'afficher du texte est 'echo' suivi d'un espace et du texte à afficher
# entre guillemets. Dans l'exemple si dessous, la commande sera directement exécutée
# via le terminal. Le '$' est l'invite de commande du terminal.
# Par exemple donc :
$ echo "Hello World"
# Il affichera comme résultat sur la ligne suivante :
Hello World
--------------
V1='Hello World'
echo $V1
Un tableau[1] :
T[0]='Hello'
T[1]='World'
echo ${T[0]} ${T[1]}
# ou
echo ${T[*]}
# ou
for V in ${T[*]}
do echo $V
done
Références
[modifier | modifier le wikicode]
Notions essentielles du shell bash
Commandes shell
[modifier | modifier le wikicode]
Définition |
Une commande shell est une chaîne de caractères en minuscules qui peut être invoquée au travers d'une invite de commande ou d'un script. Des options et des arguments peuvent la compléter. Ceux-ci sont généralement appelés paramètres de la commande. |
Exemples de commande bash :
ls ls -l /tmp cd /tmp cp liste.pdf /pub/pdf cp -r repertoire/ /pub/
Syntaxe
[modifier | modifier le wikicode]La syntaxe générique d'une commande shell est :
commande [options [argument1 [argument2 [... ]]]]
où une chaîne de caractères entre crochets est optionnelle.
Le nombre d'argument peut être limité (se reporter au manuel de la commande).
Les options de la commande peuvent être :
- des options courtes formées par un tiret suivi d'une lettre. Exemple :
-s
- des options longues formées par deux tirets suivis d'un mot. Exemple :
--size
- des options courtes ou longues qui exigent un argument. Exemples :
--speed 50
ou-s 50
Informations sur les commandes
[modifier | modifier le wikicode]La commande whereis
permet de rechercher les fichiers exécutables, les sources et les pages de manuel d'une commande Par exemple :
$ whereis python python: /usr/bin/python2.3 /usr/bin/python /etc/python2.3 /usr/lib/python2.3 /usr/lib/python2.4 /usr/local/lib/python2.3 /usr/include/python2.3 /usr/share/man/man1/python.1.gz
signifie qu'il existe sur le système plusieurs commandes python dans différents répertoire. La page du manuel se trouve dans /usr/share/man/man1/
.
La commande which
permet de savoir quel est le fichier exécuté lorsque l'on entre le nom d'une commande. Par exemple :
$ which python /usr/bin/python
signifie que le code de la commande python
utilisée par le système d'exploitation se trouve dans le répertoire /usr/bin/
.
Enfin, whatis
permet de savoir rapidement à quoi sert une commande. Exemple :
$ whatis python python (1) - an interpreted, interactive, object-oriented programming language
Manuel
[modifier | modifier le wikicode]Pour obtenir des informations plus complètes sur l'usage et l'utilité d'une commande, il suffit d'invoquer le manuel en ligne de commande : man nom_de_la_commande
. Pour sortir du manuel, composer la combinaison de touche esc : q
.
$ man echo Remise en forme de echo(1), attendez SVP... ECHO(1) Manuel de l'utilisateur Linux ECHO(1) NOM echo - Afficher une ligne de texte. SYNOPSIS echo [-neE] [message ...] echo {--help,--version} DESCRIPTION Cette page de manuel documente la version GNU de echo. La plupart des shells ont une commande interne ayant le même nom et les mêmes fonctionnalités. echo écrit chaque message sur la sortie standard, avec une espace entre chacun d'eux, et un saut de ligne après le dernier. OPTIONS -n Ne pas effectuer le saut de ligne final. -e Interprète les séquences de caractères précédées d'un backslash '\' suivantes : \a alerte (sonnerie) \b retour en arrière d'un caractère \c supprimer le saut de ligne final \f saut de page \n saut de ligne \r retour chariot \t tabulation horizontale \v tabulation verticale \\ backslash \nnn le caractère de code ASCII nnn (en octal) -E Désactiver les interprétations des séquences spéciales. OPTIONS GNU Quand la version GNU de echo est appelée avec exactement un argument, les options suivantes sont reconnues : --help Afficher un message d'aide sur la sortie standard et se terminer normalement. --version Afficher un numéro de version sur la sortie standard et se terminer normalement. TRADUCTION Christophe Blaess, 1996-2003. |
Exemple : consultation du manuel pour la commande echo
|
En particulier, la page manuel de bash fourni une documentation quasi-complète. Elle est correctement traduite en français.
$ man bash
Enchaînements de commandes
[modifier | modifier le wikicode]Enchaînements simples
[modifier | modifier le wikicode]Exécutions simultanées
[modifier | modifier le wikicode]com1 & com2 & com3 & ... & comN
Les commandes com1
jusqu'à comN
sont exécutées parallèlement.
Exécutions successives
[modifier | modifier le wikicode]com1 ; com2 ; ... ; comN
Les commandes com1
jusqu'à comN
sont exécutées successivement, les unes après les autres.
Enchaînements conditionnels
[modifier | modifier le wikicode]Et... et ... et
[modifier | modifier le wikicode]com1 && com2 && ... && comN
Dans ce cas, la commande comP
ne s'exécute que si com(P-1)
s'est soldée par un succès.
Exemple :
$ echo toto && echo jojo && echo sidonie toto jojo sidonie $ [ 1 -gt 2 ] && echo jojo $
Dans le premier cas echo toto && echo jojo && echo sidonie
, toutes les propositions sont justes, donc elles sont toutes exécutées. Dans le second [ 1 -gt 2 ] && echo jojo
, la première partie [ 1 -gt 2 ]
teste si 1 est plus grand que 2. Comme cette assertion est fausse, la deuxième partie n'est pas exécutée.
Cette structure est souvent utilisée pour programmer plus rapidement une structure conditionnelle de type if. Par exemple, les deux séries de commandes suivantes produisent le même résultat :
[ $note -gt 10 ] && echo "tu as la moyenne"
if [ $note -gt 10 ] then echo "tu as la moyenne" fi
Alternative
[modifier | modifier le wikicode]com1 || com2 || ... || comN
Dans cet exemple les commandes com1
jusqu'à comN
sont exécutées successivement tant qu'aucune ne se termine correctement. Dès qu'une des commandes se solde par un succès, la commande alternative est terminée.
Exemple :
$ echo toto || echo jojo || echo sidonie toto $ [ 1 -gt 2 ] || echo jojo jojo
Variables
[modifier | modifier le wikicode]Affectation
[modifier | modifier le wikicode]Pour affecter une valeur à une variable, la syntaxe est la suivante :
variable=valeur
place la valeur
dans la variable
. La portée de cette variable est locale au processus shell qui l'a définie.
Il faut faire très attention à ne pas placer d'espaces ni avant ni après le signe égal lors d'une affectation en bash. Ainsi, l'expression variable =valeur
engendrera l'erreur variable: not found
et variable= valeur
donnera l'erreur valeur: not found
.
Bash utilise le mécanisme de typage dynamique : il n'est donc pas nécessaire de spécifier un type pour une nouvelle variable.
Un nom de variable peut contenir des chiffres, des lettres et des symboles souligné mais ne doit pas commencer par un chiffre. La plupart du temps, les variables du shell bash sont des chaînes de caractères.
Substitution
[modifier | modifier le wikicode]On peut vérifier le contenu d'une variable à l'aide de la commande echo
:
$ variable=5
$ echo $variable
5
Ce mécanisme qui différencie la variable de son contenu est nommé substitution. On peut en faire l'expérience grâce aux commandes suivantes :
$ variable=5
$ echo variable
variable
$ echo $variable
5
Par convention, le symbole $
représente l'invite de commande.
Concaténation
[modifier | modifier le wikicode]prefix="préfixe"
suffix="suffixe"
echo "${prefix}_milieu_${suffix}"
préfixe_milieu_suffixe
Variables réservées
[modifier | modifier le wikicode]Certaines variables ont une signification spéciale réservée[1]. Elles sont utilisées lors de la création de scripts :
- pour récupérer les paramètres transmis sur la ligne de commande,
- pour savoir si une commande a échoué ou réussi,
- pour automatiser le traitement de tous paramètres.
Voici la liste de ces variables :
$0
: nom du script. Plus précisément, il s'agit du paramètre 0 de la ligne de commande, équivalent deargv[0]
$1
,$2
, ...,$9
: respectivement premier, deuxième, ..., neuvième paramètre de la ligne de commande$*
: tous les paramètres vus comme un seul mot$@
: tous les paramètres vus comme des mots séparés :"$@"
équivaut à"$1" "$2"
...$#
: nombre de paramètres sur la ligne de commande$-
: options du shell$?
: code de retour de la dernière commande. Vaut généralement 0 si cette commande s'est bien déroulée, et un autre nombre correspondant à un type d'erreur, décrit par la commandeerrno
[2].$$
: PID du shell$!
: PID du dernier processus lancé en arrière-plan$_
: dernier argument de la commande précédente
Variables d'environnement
[modifier | modifier le wikicode]Une variable d'environnement est une variable accessible par tous les processus fils du shell courant. Pour créer une variable d'environnement, on exporte la valeur d'une variable avec la commande export
.
export variable
Pour illustrer la différence entre une variable locale et une variable d'environnement, il suffit de créer une variable d'environnement, de lancer un shell fils et d'afficher la variable.
$ ma_variable=toto $ export ma_variable $ bash $ echo $ma_variable toto $ exit
Dans ce cas, la valeur de la variable est accessible depuis le shell fils. Si on essaye de faire la même chose sans exporter la variable, la valeur ne sera pas accessible.
$ ma_variable=toto $ bash $ echo $ma_variable $ exit
La commande env
permet de récupérer la liste des variables d'environnement du système d'exploitation. D'une manière générale, les variables d'environnement sont notées en majuscules.
$ env REMOTEHOST=pcloin HOST=machine.univ-autonome.fr TERM=xterm-color SHELL=/bin/bash SSH_CLIENT=::ffff:197.123.57.3 55747 22 SSH_TTY=/dev/pts/0 http_proxy=http://proxy.univ-autonome.fr:3128/ GROUP=shadogroup USER=shadouser temp=2.6.20.1 HOSTTYPE=i386-linux MAIL=/var/mail/shadouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/game PWD=/home/shadouser EDITOR=/bin/vi LANG=fr_FR@euro temp1=Linux PS1=\[\033[0;31m\]-->\T<--\[\033[0;34m\][\u@\h]\w[$]\[\033[0;32m\] --> \[\033[0;34m\] PS2=> SHLVL=2 HOME=/home/shadouser OSTYPE=linux VENDOR=intel MACHTYPE=i386 LOGNAME=patin SSH_CONNECTION=::ffff:197.123.57.3 55747 ::ffff:199.1.1.62 22 _=/usr/bin/env |
Utilisation de la commande env : consultation des variables d'environnement sur station Linux |
Quotes, apostrophe, guillemets et apostrophe inversée
[modifier | modifier le wikicode]Simple quote ou apostrophe
[modifier | modifier le wikicode]Les simples quotes délimitent une chaîne de caractères. Même si cette chaîne contient des commandes ou des variables shell, celles-ci ne seront pas interprétées. Par exemple :
$ variable="secret" $ echo 'Mon mot de passe est $variable.' Mon mot de passe est $variable.
Doubles quotes ou guillemets
[modifier | modifier le wikicode]Les doubles quotes délimitent une chaîne de caractères, mais les noms de variable sont interprétés par le shell. Par exemple :
$ variable="secret" $ echo "Mon mot de passe est $variable." Mon mot de passe est secret.
Ceci est utile pour générer des messages dynamiques au sein d'un script.
Back-quote, apostrophe inversée ou accent grave
[modifier | modifier le wikicode]Bash considère que les Back-quotes délimitent une commande à exécuter. Les noms de variable et les commandes sont donc interprétés. Par exemple :
$ echo `variable="connu"; echo "Mon mot de passe est $variable."` Mon mot de passe est connu.
Autre exemple :
echo `ls`
Cette commande affiche le contenu du répertoire courant à l'écran. Elle est strictement équivalente à ls
.
Le caractère apostrophe inversée est obtenu sur les clavier PC français par la combinaison Alt Gr + 7 et se trouve à gauche de la touche retour sur les clavier Macintosh.
Interactions avec le système de fichiers
Fichiers et répertoires
[modifier | modifier le wikicode]Créer
[modifier | modifier le wikicode]Création d'un fichier
[modifier | modifier le wikicode]Pour créer un fichier texte, le plus simple est d'utiliser l'éditeur de texte vi. Pour créer un fichier vide, il suffit d'utiliser la commande touch
. La commande ls
permet de recenser le contenu d'un répertoire.
Exemple :
$ ls $ touch vide $ ls -l total 0 -rw-r--r-- 1 shadouser shadogroup 0 2007-03-03 10:20 vide
Création d'un répertoire
[modifier | modifier le wikicode]Pour créer un répertoire, utiliser la commande mkdir
.
Exemple :
$ ls $ mkdir dossier $ ls -l total 4 drwxr-xr-x 2 shadouser shadogroup 4096 2007-03-03 10:28 dossier
Déplacer et renommer
[modifier | modifier le wikicode]Pour déplacer un objet du système de fichier, utiliser la commande mv
.
Exemple :
$ pwd /home/shadouser/test $ ls -l total 4 drwxr-xr-x 2 shadouser shadogroup 4096 2007-03-03 10:28 dossier -rw-r--r-- 1 shadouser shadogroup 0 2007-03-03 10:20 vide $ ls -l ~/ total 0 $ mv vide .. $ ls dossier $ ls .. vide
Pour renommer un fichier, il suffit de le déplacer vers un autre nom de fichier. Exemple :
$ ls vide $ mv vide plein $ ls plein
Copier
[modifier | modifier le wikicode]Pour copier un fichier, utiliser la commande cp
comme suit :
$ pwd /home/shadouser/test $ ls dossier vide $ cp vide dossier/ $ ls dossier/ vide $ ls dossier vide
Pour copier un répertoire, utiliser l'option -r
.
Supprimer
[modifier | modifier le wikicode]La commande rm
détruit un fichier. Attention, ce fichier ne pourra pas être récupéré ou difficilement.
Exemple :
$ ls plein $ rm plein $ ls
Pour supprimer un répertoire, utiliser l'option -r
. Pour forcer la suppression, utiliser l'option -f
Lister
[modifier | modifier le wikicode]Pour lister tous les fichiers du dossier courant et de ses sous-dossiers on peut utiliser ls -R
. Toutefois le formatage du code est ordonné par sous-dossier. Pour avoir une seule liste de fichiers et sous-dossiers triés, il faut donc formater ce résultat avec "awk"[3] :
ls -R | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'
Déplacements dans un système de fichier
[modifier | modifier le wikicode]L'organisation, les chemins
[modifier | modifier le wikicode]Il faut toujours se souvenir que du point de vue d'un système de type UNIX, tout est fichier. Cela signifie que, pour le système, les périphériques - disques durs, écrans, imprimantes etc... - sont représentés par des fichiers. Les répertoires sont eux aussi des fichiers, d'un type particulier, puisqu'il "contiennent" d'autres fichiers. Le lecteur comprendra donc qu'il est important de maîtriser les notions de bases concernant la manipulation de fichiers.
Les fichiers d'un tel système sont organisés sous forme d'une arborescence dont la racine est représentée par le slash : /
C'est par ce signe que débute tout chemin absolu menant à un fichier, sous réserve, bien entendu, de son existence. Pour indiquer un nœud dans ce chemin, une bifurcation, on utilise comme séparateur le slash.
Exemple :
/home/aniko/latex/rapport.tex
Ce chemin mène à un fichier baptisé "rapport.tex" qui se trouve dans un répertoire "latex", lui-même dans le répertoire "aniko", inclus dans "home" qui est un répertoire directement accessible depuis la racine. Cette organisation permet une grande souplesse, puisqu'il est aisé de détacher une partie de l'arborescence pour la greffer ailleurs. En outre cela permet de compartimenter clairement l'organisation du système, puisque par le jeu de différents droits sur les fichiers, tous ne sont pas lisibles, modifiables ou exécutables par tous les utilisateurs.
Les commandes cd
et pwd
[modifier | modifier le wikicode]La commande cd
, i.e. common directory (répertoire courant), permet de se déplacer dans le système de fichiers. La commande pwd
, i.e. present working directory, affiche l'endroit où l'on se trouve actuellement dans le système de fichiers.
Exemple :
$ pwd /home/shadouser $ ls -l total 4,0K drwxr-xr-x 4 shadouser shadogroup 4096 2007-03-03 10:31 tmp $ cd tmp $ pwd /home/shadouser/tmp $ cd .. $ pwd /home/shadouser $ cd . $ pwd /home/shadouser $ cd tmp $ pwd /home/shadouser/tmp $ cd ~/ $ pwd /home/shadouser
Des symboles sont utilisés pour représenter les répertoires couramment utilisés :
- . désigne le répertoire courant, celui dans lequel on se trouve,
- .. désigne le répertoire parent de celui dans lequel on se trouve,
- ~ désigne le répertoire personnel de l'utilisateur, dans l'exemple précédent
/home/shadouser
. La variable d'environnement$HOME
détient l'information sur le répertoire personnel de l'utilisateur.
"Monter" une ressource dans le système de fichiers
[modifier | modifier le wikicode]Les systèmes de fichiers Unix ne comprennent, comme nous le décrivons plus haut, qu'une seule arborescence logique. La racine de cette arborescence est nommée /
. Il est possible d'intégrer sous cette arborescence tout type de périphérique : souris, disque dur, lecteur dvd, ou clé usb. La commande mount
permet d'insérer une ressource dans cette arborescence.
Exemple :
$ mount -t ext3 /dev/hda2 /tmp
Cette commande permet de monter la ressource identifiée par le système comme /dev/hda2
dans le répertoire /tmp
. Il s'agit probablement d'une partition de disque dur dont le format est ext3. Cela signifie que pour accéder à cette ressource il suffit d'aller dans ce répertoire.
Exemple :
mount -t nfs pc33:/pub/ /home/sidonie/import/
Cette commande permet de monter le répertoire /pub
du système de fichier du serveur distant pc33
dans l'arborescence de la machine à travers le réseau en utilisant NFS.
Exemple :
mount -t vfat /dev/sda /home/sidonie/cle/
Cette commande permet de monter une clé usb.
Umount :
umount /home/sidonie/cle/
Cette commande permet de démonter le lecteur monté sur /home/sidonie/cle.
Flux et redirections
En Bash
[modifier | modifier le wikicode]Chaque application lancée en Bash a les flux d'entrée/sortie (stdin, stdout, stderr) que lui confère l'environnement bash (cf man : ENVIRONNEMENT D'EXÉCUTION DES COMMANDES), en plus des flux stocké (fichier) ou en transit(ex : tube nommé)
Sous les systèmes Unix, chaque processus possédera trois descripteurs de flux :
- l'entrée standard, qui permet d'envoyer des données au programme,
- la sortie standard, qui est utilisée pour afficher les résultats d'un programme,
- la sortie standard des erreurs, qui permet d'afficher les messages correspondant aux erreurs survenues lors de l'exécution du programme.
Par défaut les deux flux de sortie sont envoyés sur le terminal de l'utilisateur (écran) et l'entrée prend ses données depuis le clavier. Tout comme avec les fichiers standards, il est possible de lire (sortie) et d'écrire (entrée) sur les descripteurs de flux.
Exemple : descripteurs de flux d'un processus |
Boîte à outils redirectionnels
[modifier | modifier le wikicode]Les trois flux standards peuvent être redirigés vers d'autres sources autres que le clavier ou l'écran. Par exemple, on peut ordonner à un processus de diriger sa sortie standard vers un fichier. Pour cela, les numéros des descripteurs de flux sont utilisés. Les outils pour réaliser ces redirections sont les suivants :
- > redirige le flux de sortie de la commande pour la placer dans un fichier. Par défaut, si rien n'est précisé, le flux redirigé est la sortie standard, i.e.
>
est équivalent à1>
. Pour rediriger la sortie d'erreur standard, on utilise2>
. - < redirige le flux d'entrée de la commande pour la prendre dans un fichier,
- | redirige la sortie standard de la commande de gauche sur l’entrée standard de la commande de droite,
- >> redirige le flux de sortie de la commande pour l’ajouter à la fin d’un fichier existant.
cat tautologique
[modifier | modifier le wikicode]La commande cat
recopie l'entrée standard sur la sortie standard. Pour quitter cette commande, utiliser la combinaison de touches CTRL D. Par exemple :
$ cat je pense je pense donc donc je suis je suis
Par défaut, cat
prend ses données en entrée ligne par ligne. Ce qui explique qu'à chaque fois que l'on tape entrée, les caractères inscrits sur l'entrée standard via le clavier sont recopiés sur la sortie standard. Cette commande peut prendre un fichier comme entrée standard.
Exemple :
$ cat monfichier Affichage du contenu de mon fichier. $
Redirection de la sortie standard
[modifier | modifier le wikicode]On peut utiliser cat pour créer un fichier texte rapidement, en utilisant la redirection de la sortie standard vers un fichier. Exemple :
$ cat > journal Voici les premières lignes de mon journal. Riches de sens, elles sont le fruit d'un intense travail. $ cat journal Voici les premières lignes de mon journal. Riches de sens, elles sont le fruit d'un intense travail.
Souvent, dans les scripts bash, on utilise l'astuce suivante pour créer un fichier texte dynamiquement :
$ cat <<FIN > fichier Ce fichier contient des données très importantes. Son contenu est généré dynamiquement via un script. cat cesse d'enregistrer lorsque les caractères stipulant la fin sont donnés à l'entrée standard. Dans ce cas, il s'agit de : FIN $ cat fichier Ce fichier contient des données très importantes. Son contenu est généré dynamiquement via un script. cat cesse d'enregistrer lorsque les caractères stipulant la fin sont donnés à l'entrée standard. Dans ce cas, il s'agit de : $
Pour ajouter du contenu à un fichier, il suffit d'utiliser >>
.
Redirection de la sortie d'erreur standard
[modifier | modifier le wikicode]La bonne gestion des messages d’erreur est une des clés de la réussite d’un script. Il est possible de collecter proprement ces messages grâce à la redirection. Lorsqu'on lance la commande cat
sur un fichier qui n'existe pas, on obtient un message d'erreur No such file or directory
. On peut vérifier que ce message est un bien un message d'erreur en redirigeant la sortie d'erreur standard vers un fichier.
$ cat toto cat: toto: No such file or directory $ cat toto 2>erreur.log $ ls erreur.log $ cat erreur.log cat: toto: No such file or directory
Concaténation dans un fichier
[modifier | modifier le wikicode]Par défaut, lorsque l'on redirige la sortie standard d'un processus dans un fichier, ce fichier est écrasé par le nouveau contenu. Dans le cas d'un journal d'erreur, ceci peut s'avérer fâcheux, car la journalisation est écrasée à chaque nouveau message. Pour concaténer un message au contenu existant d'un fichier, on utilise >>
. En poursuivant l'exemple du paragraphe précédent, on obtient :
$ cat titi 2>>erreur.log $ cat erreur.log cat: toto: No such file or directory cat: titi: No such file or directory
Tubes
[modifier | modifier le wikicode]Un tube permet de rediriger la sortie standard d'une commande vers l'entrée standard d'une autre commande.
commande1 | commande2
ou pour connecter en plus la sortie d'erreur de la commande1 sur l'entrée de la commande2:
commande1 |& command2
La commande suivante ls|grep "conf$"
liste le contenu d'un répertoire et ne sélectionne que les fichiers dont le nom se termine par conf
. La figure suivante illustre la redirection de la sortie standard de ls
(la liste des fichiers d'un répertoire) vers l'entrée standard de la commande grep
.
Illustration : Tube Unix de la commande ls | grep "conf$"
|
Résumé des outils de redirection
[modifier | modifier le wikicode]com > fic
redirige la sortie standard decom
dans le fichierfic
,com 2> fic
redirige la sortie des erreurs decom
dans le fichierfic
,com 2>&1
redirige la sortie des erreurs decom
vers la sortie standard decom
,com < fic
redirige l'entrée standard decom
dans le fichierfic
,com1 | com2
redirige la sortie standard de la commandecom1
vers l'entrée standard decom2
.com1 |& com2
branche ("connecte" selon le manuel bash) la sortie standard et la sortie d'erreur decom1
sur l'entrée decom2
Tests
Conditions
[modifier | modifier le wikicode]Deux syntaxes équivalentes permettent de tester des expressions : [ expression ]
et test expression
. Elles renvoient toutes les deux un code de retour valant 0 si l'expression est vraie et 1 si l'expression est fausse.
Attention en shell (bin bash) on ne met pas de if avec des = , on utilise les valeurs eq, lt etc...)
$ [ 2 = 2 ]
$ echo $?
0
$ [ 2 = 3 ]
$ echo $?
1
La commande test
fonctionne de manière complétement équivalente :
$ test 2 = 2
$ echo $?
0
$ test 2 = 3
$ echo $?
1
Les opérateurs de tests disponibles sont, pour les chaînes :
c1 = c2
, vrai si c1 et c2 sont égales ;c1 != c2
, vrai si c1 et c2 sont différentes ;-z c
, vrai si c est une chaîne vide ;-n c
, vrai si c n'est pas une chaîne vide.
Pour les nombres :
n1 -eq n2
, vrai si n1 et n2 sont égaux (equal) ;n1 -ne n2
, vrai si n1 et n2 sont différents (non equal);n1 -lt n2
, vrai si n1 est strictement inférieur à n2 (lower than);n1 -le n2
, vrai si n1 est inférieur ou égal à n2 (lower or equal);n1 -gt n2
, vrai si n1 est strictement supérieur à n2 (greater than) ;n1 -ge n2
, vrai si n1 est supérieur ou égal à n2 (greater or equal).
Pour les expressions :
! e
, vrai si e est fausse ;e1 -a e2
, vrai si e1 et e2 sont vraies ;e1 -o e2
, vrai si e1 ou e2 est vraie.
Test if
[modifier | modifier le wikicode]L'instruction if
permet d'effectuer des opérations si une condition est réalisée.
if condition
then instruction(s)
fi
L'instruction if
peut aussi inclure une instruction else permettant d'exécuter des instructions dans le cas ou la condition n'est pas réalisée.
if condition
then instruction(s)
else instruction(s)
fi
Il est bien sur possible d'imbriquer des if
dans d'autres if
et notamment des constructions telles que celle ci sont assez courantes :
if condition1
then instruction(s)
else
if condition2
then instruction(s)
else
if condition3
...
fi
fi
fi
Pour permettre d'alléger ce type de code, ksh fournit un raccourci d'écriture : elif
. Le code précédent pourrait être réécrit ainsi :
if condition1
then instruction(s)
elif condition2
then instruction(s)
elif condition3
...
fi
Test case
[modifier | modifier le wikicode]L'instruction case
permet de comparer une valeur avec une liste d'autres valeurs et d'exécuter un bloc d'instructions lorsque une des valeurs de la liste correspond.
case valeur_testee in
valeur1) instruction(s);;
valeur2) instruction(s);;
valeur3) instruction(s);;
* ) instruction_else(s);;
...
esac
Ce code est équivalent à :
if [ valeur_teste = valeur1 ]
then instruction(s)
elif [ valeur_testee = valeur2 ]
then instruction(s)
elif [ valeur_testee = valeur3 ]
then instruction(s)
...
else
instruction_else(s)
fi
Syntaxe du test
[modifier | modifier le wikicode]Deux syntaxes équivalentes permettent de réaliser des tests sur des opérandes:
[ expression ]
ou
test expression
Ces deux commandes renvoient un code de retour valant 0 si l'expression est vraie et 1 si l'expression est fausse.
Exemple :
$ [ "salut" = "salut" ] $ echo $? 0 $ [ 2 -eq 3 ] $ echo $? 1 $ [ -f /tmp/fichier ] $ echo "file exist"
La commande test
fonctionne de manière complètement équivalente :
$ test "salut" = "salut" $ echo $? 0 $ test 2 -eq 3 $ echo $? 1
mais certains lancements peuvent être fait sous certaine condition système:
pidof api && do_some_thing || exit
Tester une variable
[modifier | modifier le wikicode]Il est tout à fait possible de tester le contenu d'une variable avec les commandes test
ou [
:
[ $a = toto ]
la substitution de la variable par sa valeur est alors effectuée et le test est vrai si la variable contient la valeur toto
et faux sinon. Par contre, si la variable a
n'est pas définie lors du test, la substitution de la ligne sera :
[ = toto ]
ce qui provoquera une erreur. Il est donc préférable de toujours protéger une variable lors d'un test soit avec des guillemets :
[ "$a" = toto ]
soit avec un préfixe :
[ x$a = xtoto ]
Attention, dans ce cas un caractère espace dans $a pose quand même un problème s'il est substitué. Il faut donc préférer la solution précédente.
Tests sur les objets du système de fichiers
[modifier | modifier le wikicode]Les opérateurs de tests disponibles sont, pour les objets du système de fichiers :
[ -e $FILE ]
vrai si l'objet désigné par $FILE existe dans le répertoire courant,
[ -s $FILE ]
vrai si l'objet désigné par $FILE existe dans le répertoire courant et si sa taille est supérieure à zéro,
[ -f $FILE ]
vrai si l'objet désigné par $FILE est un fichier dans le répertoire courant,
[ -r $FILE ]
vrai si l'objet désigné par $FILE est un fichier lisible dans le répertoire courant,
[ -w $FILE ]
vrai si l'objet désigné par $FILE est un fichier inscriptible dans le répertoire courant,
[ -x $FILE ]
vrai si l'objet désigné par $FILE est un fichier exécutable dans le répertoire courant,
[ -d $FILE ]
vrai si l'objet désigné par $FILE est un répertoire dans le répertoire courant,
[ -L $FILE ]
vrai si l'objet désigné par $FILE est un lien.
[ -N $FILE ]
vrai si l'objet désigné par $FILE à été modifié depuis la dernière lecture.
Tests sur les chaînes de caractères
[modifier | modifier le wikicode]Les opérateurs de tests disponibles sont, pour les chaînes :
[ c1 = c2 ]
vrai si c1 et c2 sont égales,[ c1 != c2 ]
vrai si c1 et c2 sont différentes,[ -z c ]
vrai si c est une chaîne vide (Zero),[ -n c ]
vrai si c n'est pas une chaîne vide (Non zero).
Tests sur les nombres (entiers)
[modifier | modifier le wikicode]Pour les nombres :
[ n1 -eq n2 ]
vrai si n1 et n2 sont égaux (EQual),
[ n1 -ne n2 ]
vrai si n1 et n2 sont différents (Not Equal),
[ n1 -lt n2 ]
vrai si n1 est strictement inférieur à n2 (Less Than),
[ n1 -le n2 ]
vrai si n1 est inférieur ou égal à n2 (Less or Equal),
[ n1 -gt n2 ]
vrai si n1 est strictement supérieur à n2 (Greater Than),
[ n1 -ge n2 ]
vrai si n1 est supérieur ou égal à n2 (Greater or Equal).
Tests et logique
[modifier | modifier le wikicode]Ou comment introduire une alternative logique :
[ ! e ]
vrai si e est fausse. ! est la négation.
[ e1 -a e2 ]
vrai si e1 et e2 sont vraies. -a ou le et logique (And).
[ e1 -o e2 ]
vrai si e1 ou e2 est vraie. -o ou le ou logique (Or).
Un exemple complet
[modifier | modifier le wikicode]#!/bin/bash
read -p "Si vous etes d'accord entrez o ou oui : " reponse
if [ ! "$reponse" = "o" -a ! "$reponse" = "oui" ]; then
echo "Non, je ne suis pas d'accord !"
else
echo "Oui, je suis d'accord"
fi
L'exemple montre la manière dont on utilise des négations avec un et logique. En particulier, il ne faut pas utiliser de parenthèses. Le non (le point d'exclamation) s'applique à la proposition logique qui vient ensuite (seulement "$reponse" = "o"). À noter que read -p permet de poser une question et de stocker la réponse de l'utilisateur dans une variable.
Calculs
Trois méthodes permettent d'effectuer des calculs, la première utilise la syntaxe spéciale $((operation))
, la seconde utilise la commande let
. La troisième utilise la commande bc
, qui accepte aussi les nombres décimaux. Taper bc
seul sur la ligne de commande permet de passer en mode interactif. Voici comment on peut incrémenter une variable avec chacune des méthodes :
$ a=1
$ a=$(($a + 1))
$ echo $a
2
$ a=1
$ let "a=$a + 1"
$ echo $a
2
$ a=1
$ a=$(echo "$a+1" |bc )
$ echo $a
2
mais il est possible "dans certaines circonstances" (man bash,ÉVALUATION ARITHMÉTIQUE) de réaliser des opérations plus complexes:
a=1; let a++; echo $a
let argument [argument] (cf man bash,COMMANDES INTERNES DE L'INTERPRÉTEUR)
Calcul avancé avec bc
[modifier | modifier le wikicode]En natif, Bash ne propose que des fonctionnalités de calcul limitées (additions simples ...). bc
permet des calculs plus complexes, avec gestion des décimales (ne pas oublier l'option -l
). Exemple :
$ echo "1/3" |bc -l
.33333333333333333333
Calcul d'une racine carrée :
$ echo "sqrt(2)" |bc -l
1.41421356237309504880
Structures conditionnelles
if
[modifier | modifier le wikicode]Test simple
[modifier | modifier le wikicode]L'instruction if
permet d'effectuer des opérations si une condition est réalisée.
if condition
then
instruction(s)
fi
Dans ce cas condition
est une commande et l'expression conditionelle est exécutée si son code de retour vaut zéro. Par exemple
if pkg-config gtk+-2.0
then
echo "gtk+ est installé sur votre système"
fi
exécute le programme pkg-config
avec le paramètre gtk+-2.0
et exécute echo "gtk+ est installé sur votre système"
si la valeur de retour de pkg-config
est zéro. Il est bien sur possible d'utiliser des enchainements de commandes, ainsi :
if pkg-config gtk+-2.0 && pkg-config gtkglext-1.0
then
echo "gtk+ et gtkglext sont installés sur votre système"
fi
n'affichera quelque chose que si les deux appels à pkg-config
ont un code de retour à 0.
Comme vu précédemment, test
et [
renvoient un code égal à zéro si une condition est vraie et différent de zéro sinon, il est donc possible de les utiliser avec une instrution if
:
if [ "$mavariable" = "unevaleur" ]
then
echo "ma variable a la bonne valeur"
fi
Test avancé
[modifier | modifier le wikicode]L'instruction if
peut aussi inclure une instruction else permettant d'exécuter des instructions dans le cas où la condition n'est pas réalisée.
if condition
then
instruction(s)
else
instruction(s)
fi
Il est bien sûr possible d'imbriquer des if
dans d'autres if
et notamment des constructions telles que celle-ci sont assez courantes :
if condition1
then
instruction(s)
else
if condition2
then
instruction(s)
else
if condition3
...
fi
fi
fi
Pour permettre d'alléger ce type de code, ksh fournit un raccourci d'écriture : elif
. Le code précédent pourrait être réécrit ainsi :
if condition1
then
instruction(s)
elif condition2
then
instruction(s)
elif condition3
...
fi
case
[modifier | modifier le wikicode]L'instruction case
permet de comparer une valeur avec une liste d'autres valeurs et d'exécuter un bloc d'instructions lorsque une des valeurs de la liste correspond.
case valeur_testee in
valeur1) instruction(s);;
valeur2) instruction(s);;
valeur3) instruction(s);;
...
esac
Ce code est plus lisible que son équivalent avec if
:
if [ valeur_teste = valeur1 ]
then instruction(s)
elif [ valeur_testee = valeur2 ]
then instruction(s)
elif [ valeur_testee = valeur3 ]
then instruction(s)
...
fi
Les valeurs peuvent contenir des caractères joker, ainsi :
case $a in
t?t?) echo "ok";;
*) exit 1;;
esac
affichera ok
si la variable a
a une valeur correspondant au motif t?t?
, comme par exemple toto
ou tata
.
Boucles
Boucle for
[modifier | modifier le wikicode]Syntaxe foreach
[modifier | modifier le wikicode]La boucle for
permet de parcourir une liste de valeurs, elle effectue donc un nombre de tours de boucle qui est connu à l'avance.
for variable in liste_valeurs
do instruction(s)
done
Liste définie
[modifier | modifier le wikicode]Cet exemple est une commande qui lance une sous-commande en paramètre 1 dans plusieurs conteneurs :
CMD=$1
for app in {"app1","app2","app3"}; do
echo $app; docker-compose exec $app sh -c "$CMD"; echo ""
done
Liste de fichiers
[modifier | modifier le wikicode]Exemple pour programmer un clone de la fonction ls
:
for i in *
do
echo $i
done
Dans cet exemple, l'étoile est remplacée par tous les fichiers du répertoire courant, la boucle for
va donc donner successivement comme valeur à la variable i
tous ces noms de fichier. Le corps de la boucle affichant la valeur de la variable i
, le nom de tous les fichiers du répertoire courant sont affichés successivement.
Liste d'arguments
[modifier | modifier le wikicode]La boucle for est très souvent utilisée dans un script pour parcourir la liste des arguments fournie au script. Par exemple :
for i in "$@"
do
echo "$i"
done
liste tous les arguments transmis au script.
Liste séquentielle
[modifier | modifier le wikicode]Il est souvent utile de pouvoir effectuer une boucle sur une liste de valeurs, pour cela on utilise la fonction seq
. Cette fonction prend en arguments deux entiers et renvoie la liste de tous les entiers compris entre ces bornes.
$ seq 1 4 1 2 3 4
Utilisée conjointement avec la boucle for
, la commande seq
permet donc d'avoir un compteur de boucle :
$ for i in `seq 1 4`; do echo "tour de boucle $i"; done tour de boucle 1 tour de boucle 2 tour de boucle 3 tour de boucle 4
Seconde syntaxe
[modifier | modifier le wikicode]La boucle for
possède une deuxième syntaxe :
for ((e1;e2;e3))
do instruction(s)
done
Dans laquelle, e1
, e2
et e3
sont des expressions arithmétiques. Une telle boucle commence par exécuter l'expression e1
, puis tant que l'expression e2
est différente de zéro le bloc d'instructions est exécuté et l'expression e3
évaluée.
for ((i=0 ; 10 - $i ; i++))
do echo $i
done
Boucles until
et while
[modifier | modifier le wikicode]La boucle while
exécute un bloc d'instructions tant qu'une certaine condition est satisfaite, lorsque cette condition devient fausse la boucle se termine. Cette boucle permet donc de faire un nombre indéterminé de tours de boucle, voire infini si la condition ne devient jamais fausse.
while condition
do instruction(s)
done
#! /bin/bash
a_trouver=$((($RANDOM % 100) + 1))
let "b = 1"
let "h = 100"
read -p "entrez un nombre compris entre 1 et 100 : " i
while [ "$i" -ne "$a_trouver" ]; do
if [ "$i" -lt "$a_trouver" ]; then
let "b = $i"
adj="Trop petit"
else
let "h = $i"
adj="Trop grand"
fi
read -p "$adj, entrez un nombre compris entre ${b} et ${h} : " i
done
echo "Bravo, le nombre etait en effet $a_trouver"
La syntaxe de la boucle until
est exactement la même que celle de la boucle while
, mais sa signification est inversée : la boucle est exécutée tant que la condition est fausse.
Interactions avec l'utilisateur
Lire la saisie d'un utilisateur
[modifier | modifier le wikicode]Les commandes suivantes permettent de gérer l'interaction avec l'utilisateur :
- la commande
echo
affiche des données soit sur la sortie standard, soit sur la sortie d'erreur, - la commande
read
lit les valeurs entrées au clavier et les stocke dans une variable.
read var
permet de lire une valeur entrée au clavier par l'utilisateur et de stocker cette valeur dans la variable var
.
Exemple :
$ read a toto $ echo $a toto
Dans cet exemple, read
lit une valeur que l'utilisateur saisit au clavier en l'occurrence : toto. Cette valeur est stockée dans la variable a
. Le contenu de cette variable a
est affiché grâce à echo
et son contenu est effectivement toto
.
Si aucun nom de variable n'est fourni lors de l'appel de read
, la valeur entrée par l'utilisateur est stockée dans la variable REPLY
.
Exemple
$ read sidonie $ echo $REPLY sidonie
Interaction et case
[modifier | modifier le wikicode]Souvent, dans les scripts, on trouve la structure suivante :
read
case $REPLY in
valeur1) instruction(s);;
valeur2) instruction(s);;
valeur3) instruction(s);;
...
esac
Instruction select
[modifier | modifier le wikicode]echo "Etes vous un homme ou une femme ?"
select i in homme femme; do
if [ "$i" = "homme" ]; then
echo "Bonjour monsieur"
break
elif [ "$i" = "femme" ]; then
echo "Bonjour madame"
break
else
echo "mauvaise reponse"
fi
done
Regex
En informatique, une expression régulière ou expression rationnelle ou expression normale ou motif, est une chaîne de caractères, qui décrit, selon une syntaxe précise, un ensemble de chaînes de caractères possibles. Les expressions régulières sont également appelées regex (de l'anglais regular expression). Elles sont issues des théories mathématiques des langages formels. Les expressions régulières sont aujourd’hui utilisées pour la lecture, le contrôle, la modification, et l'analyse de textes ainsi que la manipulation des langues formelles que sont les langages informatiques.
L'exemple d'expression régulière suivant permet de valider qu'une chaîne de caractère correspond à la syntaxe d'un nombre entier non signé, c'est à dire une suite non vide de chiffres :
[0-9]+
En détails :
- Les crochets spécifient l'ensemble des caractères auquel doit appartenir le caractère courant de la chaîne. Dans cet exemple, l'ensemble est celui des chiffres de 0 à 9 inclus.
- Le caractère plus indique de répéter le motif précédent au moins une fois (suite non vide).
En Bash, le regex peut être employé depuis la version 3 après l'opérateur de comparaison =~
[4].
VALEUR=12345
if [[ $VALEUR =~ [0-9]+ ]]; then echo "Valeur entière positive"; else echo "ko"; fi
Syntaxe
[modifier | modifier le wikicode]Les expressions rationnelles peuvent être analysées et testées via un débogueur en ligne comme https://regex101.com/.
Caractère | Type | Explication |
---|---|---|
.
|
Point | N'importe quel caractère |
[...]
|
crochets | classe de caractères : tous les caractères énumérés dans la classe, avec possibilité de plages dont les bornes sont séparées par "-". Ex : [0-9a-z] pour tout l'alphanumérique en minuscule, ou [0-Z] pour tous les caractères de la table Unicode entre "0" et "Z", c'est-à-dire l'alphanumérique majuscule plus ":;<=>?@"[5].
|
[^...]
|
crochets et circonflexe | classe complémentée : tous les caractères sauf ceux énumérés. |
^
|
circonflexe | Marque le début de la chaîne ou de la ligne. |
$
|
dollar | Marque la fin de la chaîne ou de la ligne. |
|
|
barre verticale | Alternative - ou reconnaît l'un ou l'autre |
(...)
|
parenthèses | groupe de capture : utilisé pour limiter la portée d'un masque ou de l'alternative, grouper un motif répété ou capturer une séquence |
\n
|
référence | Même séquence que celle capturée précédemment par le nème groupe de capture |
\g{n}
|
référence | Même séquence que celle capturée précédemment par le nème groupe de capture |
(?P<nom>pattern)
|
Sous-motif nommé | Nomme le résultat d'un groupe de capture par un nom. |
\g{nom}
|
référence | Même séquence que celle capturée précédemment par le groupe de capture nommé nom. |
Par défaut, les caractères et groupes ne sont pas répétés. Les quantificateurs permettent de spécifier le nombre de répétitions et sont spécifiés immédiatement après le caractère ou groupe concerné.
Caractère | Type | Explication |
---|---|---|
*
|
astérisque | 0, 1 ou plusieurs occurrences |
+
|
plus | 1 ou plusieurs occurrences |
?
|
interrogation | 0 ou 1 occurrence |
{...}
|
accolades | nombre de répétitions : spécifie le nombre de répétitions du motif précédent (minimum et maximum). Avec la présence de la virgule, quand le minimum est absent la valeur par défaut est zéro, quand le maximum est absent la valeur pas défaut est l'infini. Sans virgule (un seul nombre) il s'agit du nombre exact (minimum et maximum ont la même valeur). Exemples :
|
Par défaut les quantificateurs ne recherchent pas forcément la plus longue séquence de répétition possible. Il est possible de les suffixer avec un caractère pour modifier leur comportement.
Caractère | Type | Explication |
---|---|---|
?
|
réticent | Le quantificateur qui précède recherchera la plus petite séquence possible. |
+
|
possessif | Le quantificateur qui précède recherchera la plus grande séquence possible. |
Remarques :
- Les caractères de début et fin de chaîne (
^
et$
) ne fonctionnent pas dans[]
où ils ont un autre rôle. - Les opérateurs
*
et+
sont toujours avides, pour qu'ils laissent la priorité il faut leur apposer un?
à leur suite[6].
Classe | Signification |
---|---|
[[:alpha:]]
|
n'importe quelle lettre |
[[:digit:]]
|
n'importe quel chiffre |
[[:xdigit:]]
|
caractères hexadécimaux |
[[:alnum:]]
|
n'importe quelle lettre ou chiffre |
[[:space:]]
|
n'importe quel espace blanc |
[[:punct:]]
|
n'importe quel signe de ponctuation |
[[:lower:]]
|
n'importe quelle lettre en minuscule |
[[:upper:]]
|
n'importe quelle lettre capitale |
[[:blank:]]
|
espace ou tabulation |
[[:graph:]]
|
caractères affichables et imprimables |
[[:cntrl:]]
|
caractères d'échappement |
[[:print:]]
|
caractères imprimables exceptés ceux de contrôle |
Expression | Signification |
---|---|
\b |
Chaine de début ou fin de mot |
\B |
Chaine qui n'est pas début ou fin de mot |
\< |
Chaine vide en début de mot |
\> |
Chaine vide en fin de mot |
\s |
Caractères espace |
\S |
Non caractères espace |
\w |
Caractère alphanumérique : lettre, chiffre ou underscore |
\W |
Caractère qui n'est pas lettre, chiffre ou underscore |
Constructeurs spéciaux : Ces fonctions précèdent l'expression à laquelle elles s'appliquent, et le tout doit être placé entre parenthèses.
?:
: groupe non capturant. Ignorer le groupe de capture lors de la numérotation des backreferences. Exemple :((?:sous-chaine_non_renvoyée|autre).*)
.- La présence d'un groupe capturant peut engendrer une allocation mémoire supplémentaire. Si une expression régulière particulièrement complexe provoque une erreur de mémoire, essayez de remplacer les groupes capturant non référencés et inutilisés par des groupes non-capturant en ajoutant
?:
juste après la parenthèse ouvrante, et en décalant les numéros des groupes référencés.
- La présence d'un groupe capturant peut engendrer une allocation mémoire supplémentaire. Si une expression régulière particulièrement complexe provoque une erreur de mémoire, essayez de remplacer les groupes capturant non référencés et inutilisés par des groupes non-capturant en ajoutant
?>
: groupe non capturant indépendant.?<=
: positive lookbehind, vérifier (sans consommer) que ce qui précède correspond au motif spécifié. Exemple :- Chercher une lettre u précédée d'une lettre q :
(?<=q)u
- Chercher une lettre u précédée d'une lettre q :
?<!
: negative lookbehind, vérifier (sans consommer) que ce qui précède ne correspond pas au motif spécifié.?=
: positive lookahead, vérifier (sans consommer) que ce qui suit correspond au motif spécifié.?!
: negative lookahead, vérifier (sans consommer) que ce qui suit ne correspond pas au motif spécifié. Exemples :
Options :
Les options d'interprétation sont en général spécifiées à part. Mais certaines API ne permettent pas de les spécifier. Il est possible d'insérer ces options dans l'expression régulière[11].
(?optionsactivées-optionsdésactivées)
Exemples :
- Chercher un mot composé de voyelles sans tenir compte de la casse :
(?i)[AEIOUY]+
- Chercher un mot composé de voyelles en tenant compte de la casse, ici en majuscules :
(?-i)[AEIOUY]+
Les options s'appliquent à toute l'expression quelle que soit leur position dans l'expression.
Exemple
[modifier | modifier le wikicode]#exemple
if [[ "Wikibooks" =~ o+ ]]; then echo "ok"; else echo "ko"; fi
ok
if [[ "Wikibooks" =~ a+ ]]; then echo "ok"; else echo "ko"; fi
ko
#Suite de caracteres hexadecimauX
if expr "0BA2" : '^[[:xdigit:]][[:xdigit:]]*$' ; then echo "ok"; else echo "ko" ; fi
4
ok
if expr "0NA2" : '^[[:xdigit:]][[:xdigit:]]*$' ; then echo "ok"; else echo "ko" ; fi
4
ko
Références
[modifier | modifier le wikicode]- ↑ https://www.quennec.fr/book/export/html/269
- ↑ https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/
- ↑ https://stackoverflow.com/questions/1767384/ls-command-how-can-i-get-a-recursive-full-path-listing-one-line-per-file
- ↑ http://www.linuxjournal.com/content/bash-regular-expressions
- ↑ https://unicode-table.com/fr/
- ↑ https://docstore.mik.ua/orelly/webprog/pcook/ch13_05.htm
- ↑ https://www.regular-expressions.info/posixbrackets.html
- ↑ https://www.gnu.org/software/grep/manual/html_node/The-Backslash-Character-and-Special-Expressions.html
- ↑ https://www.regextester.com/15
- ↑ Jan Goyvaerts, Steven Levithan, Regular Expressions Cookbook, O'Reilly Media, Inc., (lire en ligne)
- ↑ Les options sont appelées modificateurs (modifiers en anglais), voir https://www.regular-expressions.info/modifiers.html
Fonctions
Comme pour tout autre langage, l'utilisation de fonctions facilite le développement de scripts et la structuration de ceux-ci.
Déclaration
[modifier | modifier le wikicode]Pour déclarer une fonction, il existe différentes méthodes, nous pouvons toujours utiliser la syntaxe suivante malgré le fait qu'elle soit dépréciée :
function maFonction()
{
instructions
}
La déclaration d'une fonction doit toujours se situer avant son appel.
Le mot-clé function
est optionnel :
maFonction()
{
instructions
}
Les deux syntaxes ont leur avantage :
- L'absence du mot-clé permet au script d'être compatible avec les shells Bourne et Korn.
- La présence du mot-clé permet d'éviter une collision de nom avec les alias.
Appel et paramètres
[modifier | modifier le wikicode]Appel
[modifier | modifier le wikicode]Pour appeler une fonction, on utilise la syntaxe suivante:
maFonction param_1 param_2 ... param_n
Paramètres passés à la fonction
[modifier | modifier le wikicode]Ces paramètres sont bien sûrs optionnels. À l'intérieur de la fonction, ils sont représentés, respectivement, par les variables $1, $2,... , $n. $0 représente toujours le nom du script (et non de la fonction) qui s'exécute.
Le nombre de paramètres passés à une fonction est représenté par la variable $#
Exemple:
#!/bin/bash
# déclaration d'une fonction
function maFonction()
{ local varlocal="je suis la fonction"
echo "$varlocal"
echo "Nombres de paramètres : $#"
echo $1
echo $2
}
# appel de ma fonction
maFonction "Hello" "World!"
Ce qui donne le résultat suivant:
je suis la fonction Nombres de paramètres : 2 Hello World!
Fin
[modifier | modifier le wikicode]Une fonction termine son exécution lorsqu'elle n'a plus d'instructions à exécuter ou lorsqu'elle rencontre l'instruction return
ou exit
. Ces instructions peuvent être suivies d'un entier positif, qui correspond à la valeur de retour de la fonction.
Si aucune valeur n'est spécifiée, c'est la valeur 0 qui est renvoyée.
La valeur de retour de la dernière fonction appelée est stockée dans la variable $?
Variables
[modifier | modifier le wikicode]Outre les paramètres, une fonction peut utiliser plusieurs variables:
- Réutiliser toutes les variables globales du script. Par défaut dans un script shell, les variables sont déclarées comme étant globales.
- En déclarer de nouvelles.
- Déclarer des variables locales. Pour déclarer une variable localement, il faut la faire précéder du mot clé
local
. Une telle variable ne sera utilisable que dans la fonction qui la déclare durant l'exécution de celle-ci mais sera considérée comme globale (donc connue) par les fonctions appelées à partir de cette fonction (après la déclaration locale de la variable).
Pour éviter d'accéder en lecture à une variable n'ayant pas d'existence, on peut inscrire la commande set -u en début de script.
Scripts
Définition |
Un script est une suite d’instructions, de commandes qui constituent un scénario d'actions. C’est un fichier texte que l’on peut exécuter, c’est à dire, lancer comme une commande. |
Au commencement, la ligne shebang
[modifier | modifier le wikicode]Dans la pratique, on utilise plusieurs invites de commandes pour commander des systèmes ou des applications différentes. Par exemple, il est possible d’utiliser Perl, Python, Bash, Tcsh. Il ne suffit donc pas d'écrire une suite d’instructions pour que le système puisse l'exécuter. Il faut également préciser l’interprète pour lequel ce script est écrit. C’est l’objet de la première ligne d’un script : la ligne ”shebang”. Pour un script en shell bash, elle se présente ainsi :
#!/bin/bash
Pour utiliser tcsh, alors il faut écrire :
#!/bin/tcsh
Exécution d'un script
[modifier | modifier le wikicode]Avant toute chose, il faut rendre un script exécutable. Sous Unix, il s'agit d'utiliser la commande chmod
.
$ chmod +x script.sh $ ls -l -rwxr-xr-x 1 shadouser shadogroup 26 Mar 5 15:31 script.sh
Quatre solutions sont possibles pour exécuter un script.
En utilisant ./ si l'on se trouve dans le répertoire du script :
$ ./script.sh
ou en spécifiant le chemin absolu :
$ /home/jojo/script.sh
si script se trouve dans le répertoire /home/jojo
.
Une autre solution est de modifier la variable d'environnement PATH
et d'y faire figurer le répertoire qui contient le script à exécuter. Dans ce cas, il est possible d'invoquer le script depuis n'importe quel endroit du système de fichiers.
$ PATH=$PATH:/home/jojo/ $ script.sh
Enfin, une dernière solution est d'appeler directement l'interprète et de lui transmettre le script à exécuter.
$ bash script.sh
Exemple de script
[modifier | modifier le wikicode]#!/bin/bash
for FILE in $*
do
if [ -e $FILE ]
then
echo "Le fichier $FILE est présent dans le répertoire courant."
fi
done
exit 0
Paramètres
[modifier | modifier le wikicode]Les paramètres fournis par l'utilisateur lors de l'appel de scripts sont accessibles grace aux paramètres positionnels : $0, $1, ..., $9. $0 représente le nom du script tel qu'il a été appelé, $1 est le premier argument du script, $2 le deuxième, etc. Il n'est pas possible d'accéder directement au dixième et suivant arguments de cette manière.
Une autre variable essentielle lors de la gestion des paramètres est $#
qui a pour valeur le nombre d'arguments transmis lors de l'appel du script.
#!/bin/bash
if [ $# -lt 1 ]; then
echo "Usage: $0 <votre prenom>"
exit 1
fi
echo "Bonjour $1"
#!/bin/bash
#Usage ./script je vais changer -ifs : le:nouveau:IFS
printf "je restitue des arguments 1 à 1.\nje change IFS.(cf man bash IFS/paramètres spéciaux)\n"
change=0
#cf man bash: Remplacement des paramètres
val=${@/*-ifs ? /}
args=${@/$val/}
printf "$args\n$val\n"
while test -n "$args"
do
for v in $args
do
if test $change -eq 1; then change=2; IFS="$v"; printf "<== NEW IFS: \'$IFS\' ==>\n"; fi
if test "$v" = "-ifs";then change=1; continue; fi
test $change -eq 0 && printf "==> $v\n"
test $change -eq 2 && change=0
done
args="$val"
val=""
done
Enchaînements et scripts
Scripts
[modifier | modifier le wikicode]Exécution d'un script
[modifier | modifier le wikicode]Il y a deux manières d'exécuter un script, soit en rendant le script exécutable, soit en passant le fichier comme argument à la commande ksh
.
chmod +x script ./script
ksh script
Variables spéciales
[modifier | modifier le wikicode]Plusieurs variables spéciales sont disponibles lors de l'exécution d'un script.
$0
a pour valeur le nom du script ;$1
jusqu'à$9
ont respectivement pour valeur les neuf premiers arguments du script ;$#
a pour valeur le nombre d'arguments passés au script ;$@
contient la liste de tous les arguments du script.$*
contient la liste de tous les arguments du script (décomposée).
En ksh, à partir du dixième argument, il faut coder la valeur numérique entre accolades, exemple : ${10}
pour le 10ème[1].
Pour tester si le script contient au moins un paramètre :
#!/bin/bash
if [ "x$1" = "x" ]
then echo "argument vide"
else echo "argument non vide"
fi
Enchaînements
[modifier | modifier le wikicode]Enchaînements simples
[modifier | modifier le wikicode]com1 & com2 & ... & comN
Les commandes com1
jusqu'à comN
sont exécutées parallèlement.
com1 ; com2 ; ... ; comN
Les commandes com1
jusqu'à comN
sont exécutées successivement.
Enchaînements conditionnels
[modifier | modifier le wikicode]com1 && com2 && ... && comN
Cet exemple va exécuter toutes les commandes com1
jusqu'à comN
tant que celles ci se terminent correctement.
com1 || com2 || ... || comN
Dans cet exemple les commandes com1
jusqu'à comN
seront exécutées successivement tant qu'aucune ne se termine correctement.
Références
[modifier | modifier le wikicode]
Commandes shell
Une commande, dans le sens plus général, est un fichier exécutable ou un shell builtin. Par exemple, cd, ls, echo et firefox
sont des commandes.
Les commandes builtins sont intégrées dans le bash. Pour le reste, les commandes disponibles sont celles installées sur le système. Pour cette raison, le détail des commandes varient d'une distribution à l'autre.
alias
- Vous autorise à créer un raccourci ou des noms de commande familiers ou très utiliséesat
- Exécute une ligne de commande à un moment spécifié dans le futurapropos
- Donne des informations sur la commandeawk
- Écrit uniquement le n-ième mot d'une ligne de commande en entrée et plusaspell
- Vérificateur d'orthographe interactifautoexpect
- Log les touches appuyées - Attention
bash
- Le Bourne Again SHell, un des shellsbunzip2
- Décompresse les fichiers compressés avecbzip2
bzip2
- Un outil de compression
cat
- Réception de chaîne de caractère depuis stdin ou un fichier et sortie de celui-ci par stdout ou par un fichierchgrp
- Change le groupe du propriétaire d'un fichierchmod
- Change le mode de permission d'un fichierchown
- Change le propriétaire d'un fichiercp
- Copie un fichiercpio
- Crée des fichiers d'archives dans différents formatscron
- Service planifiant des taches à exécuter à des dates spécifiquescrontab
- Contrôle le servicecron
chsh
- Change l'interpreteur de commandecut
- Affichage des colonnes d'un fichier délimité par un caractèrecvs
- Un système de gestion de version
date
- Affiche ou configure l'heure et la datedd
- Transfert du contenu d'un disque de / vers un fichier et plusdf
- Affiche la taille libre du disquediff
- Affiche la différence entre deux fichiers et plusdpkg
- Un gestionnaire de paquets pour Debian (Ubuntu…), de bas niveau sur lequel d'autres gestionnaires plus élaborés commeapt
etaptitude
reposent.du
- Affiche combien d'espace disque est utilisé par un répertoiredisown
- Retirer l'appartenance d'une tâche au processus courant (supprime lepid
d'un travail). Même quand le service tourne, celui-ci ne s'arrête pas.
echo
- Affiche une chaîne de caractères vers la sortie standard (stdout) par défaut.eject
- Ouvre le lecteur de cd (à noter queeject -t
le referme)env
- Affiche les variables d'environnementexit
- Sort de la plupart des shellsexport
- Crée et valorise une variable d'Environnement enbash
ouzsh
expect
- Est un langage de script. Peut être lié avec Python pour des tâches automatisées. Essayez la commandeautoexpect
fdisk
- Partitionne un disquefg
- Fait passer un processus de l'arrière-plan (tâche de fond) à l'avant-planfile
(commande) - Détermine le type d'un fichierfind
- Trouve des fichiers selon leur nom, taille, date de dernière modification ou autresfinger
- Cherche si quelqu'un est connectéftp
- Utiliser le protocole de transfert de fichiers (FTP) en mode texte
g++
- Compile un fichier source écrit dans le langage C++gcc
- Compile un fichier source écrit dans le langage Cgftp
- Logiciel graphique utilisant le protocole de transfert de fichiers FTPgrep
- Recherche un texte ou un motif textuel dans un ou plusieurs fichiers textegroups
- Montre à quels groupes l'utilisateur appartientgvimdiff
-diff
graphique (montre les différences entre deux fichiers texte)gunzip
- Décompresse un fichier compressé pargzip
gzip
- Compresse un fichier
halt
- Arrête l'ordinateur (root)head
- Affiche seulement les n premières lignes d'un fichierhexdump
- Affiche le contenu d'un fichier sous forme hexadécimalehistory
(commande) - Affiche l'historique des commandes utilisées dans l'interprétateur de commande (shell)hostname
- Affiche le nom de l'ordinateur
id
- Affiche les numéros d'identification de l'utilisateur et des groupes auxquels il appartientifconfig
- Affiche entre autres l'adresse IP de l'utilisateurinfo
- Affiche les informations à propos d'une commandeinit
- Redémarre ou change le niveau d'exécution du systèmeiptables
- Montre la configuration de votre pare-feuiptraf
- [1]suivi des adresses IP dynamiques sur un LAN (Limited Area Network)
jobs
- Donne une liste des travaux courants en arrière plan (processus)
kill
- Tue un processuskillall
- Tue tous les processus d'un nom donné
ldd
- Affiche les bibliothèques dynamiques dont dépend un exécutableless
- Affiche une sortie dans laquelle vous pouvez vous déplacer et effectuer des recherches. C'est un "pageur".ln
- Établit un lien vers un fichierls
- Liste le contenu d'un fichier répertoirelsmod
- Établit la liste des modules chargés par le noyaulsof
- Établit la liste des fichiers ouverts et des sockets à l'écoutelook
- Vérification rapide de l'orthographe
make
- Permet de compiler des logiciels et plusman
- Fournit une aide à propos des commandes et API du système (consultation du manuel)md5sum
- Calcule la somme de contrôle d'un fichier (permet par exemple de vérifier l'intégrité d'une copie en comparant samd5sum
à celle de la source)mkdir
- Crée un fichier répertoiremkfs
- Formate un périphérique de stockage (crée un système de fichiers)minicom
- Permet de communiquer suivant le protocole RS232 (port série)more
- Commeless
, il s'agit d'un "pageur"mount
- Prépare un périphérique de stockage à accepter la lecture et l'écrituremv
- Déplace un fichier, permet aussi de le renommer (on le déplace au même endroit en changeant son nom)
netcat
- Envoie des bits sur le réseaunetstat
- Obtient des informations sur les sockets à l'écoute et sur les ports ouvertsnice
- Fixe la priorité d'exécution d'un processusnm
- Établit la liste des noms de fonctions d'un fichier objet
objdump
- Affiche les informations relatives à un fichier objetopenssl
- Permet d'utiliser les fonctions de cryptographie qui suivent les protocoles réseaux SSL et TLS
passwd
- Change votre mot de passe ou celui d'un autre utilisateurping
- Indique si un ordinateur en particulier est fonctionnel sur un réseaups
- Affiche la liste des processus lancés à l'état actuelpwd
- Affiche le dossier actuel où se trouve l'utilisateurpaste
- Fusionne des lignes en un fichier en les combinant horizontalement
quota
- Gère la quantité de ressources qu'un utilisateur est autorisé à utiliser
rar
- Fichiers ou dossiers compressés, de type.rar
read
- Lit une ligne depuis votre clavierreboot
- Redémarre l'ordinateurrename
- Renomme des fichiers (pour un fichier, il est plus simple de passer parmv
)rm
- Efface un fichier (ou un dossier avec -r)route
- Gère la table de routage de votre réseaurpm
- Gère les paquets sous les distributions Redhat et Fedorarsync
- Permet la synchronisation de vos fichiers à travers un réseau
scp
- Effectue une copie sécurisée à travers un réseau - données chiffréesscreen
- Permet de créer plusieurs terminaux à partir d'un seulsed
- Effectue des modifications sur des chaînes de caractèressetenv
- Modifie la valeur d'une variable d'environnement d'un shell Cshutdown
- Éteint ou redémarre le systèmesleep
- Retarde d'une certaine quantité de temps à déterminerssh
- Permet de se connecter de façon sécurisée à un hôte distantsu
- Change l'identité de l'utilisateursudo
- Exécute une commande sous l'identité d'un autre utilisateur (le plus souvent "root" -/etc/sudoers
)
tail
- Ne montre que les n dernières lignes d'un fichiertar
- Archive des fichiers selon un certain formattcpdump
- Purge le trafic sur le réseau TCPtee
- Duplique la sortie standard vers un fichiertime
- Indique le temps nécessaire à une commande pour s'achevertop
- Montre les processus utilisant le plus de ressources du processeurtouch
- Crée un fichier ou modifie son étiquette temporelletraceroute
- Montre la route empruntée par un paquet sur un réseautac
- Imprime un fichier en inversant l'ordre des lignes, à l'inverse decat
(cat
Xtac
)
ulimit
- Lit ou écrit certaines limitations pour le processus en coursumount
- Démonte un périphérique (nécessite souvent les droits du groupe sudoers)uname
- Affiche la version du noyau en fonction en plus d'autres détailsuniq
- Supprime une ligne en doublon dans un fichier triéunset
- Efface de la mémoire les variables passées en paramètre (ne retourne pas de résultat)unzip
- Décompresse des fichiersunrar
- Décompresse des fichiers d'archivagerar
uptime
- Affiche la date et l'heure de la dernière mise en route de l'ordinateuruseradd
- Ajoute un utilisateuruserdel
- Supprime un utilisateurusermod
- Modifie un utilisateur
vim
- Éditeur de texte pur, fonctionnement modal. À distinguer d'un traitement de texte.Vgcreate
- Créer des groupes de volumes LVMVgdisplay
- Groupes d'affichage de volumes LVMVgs
- Afficher des informations sur les groupes de volumes LVMVgscan
- Rechercher des groupes de volumes LVMvmstat
- Affiche des informations sur l'activité des processus, de la mémoire, des signaux, du processeur, des disques durs, des entrées et sorties, etc.
who
- Affiche qui est connecté sur le systèmewhich
- Affiche le chemin d'un fichier exécutablewhoami
- Affiche votre véritable nom d'utilisateurwc
- Word count ; permet de compter des bits, des caractères, des lignes, des mots dans un fichierwrite
- Envoie un message à un autre utilisateur connecté
xargs
- Exécute des commandes en utilisant pour arguments les données issues de l'entrée standard (pratique pour utiliser des commandes comme des filtres alors que ce n'en sont pas)xev
- Affiche tous les événements relatifs à une fenêtrexkill
- “Tue” une fenêtre de processus en le déconnectant du serveur Xxosview
- Affiche l'activité du processeur, de la mémoire, des disques-durs et plus encore…
yacc
- Générateur de programmes d'analyse syntaxique écrits en Cyes
- Affiche continuellement une chaîne de caractèresyum
- Un gestionnaire de paquets utilisé par les distributions Redhat et Fedorayast
- Un gestionnaire de paquets utilisé par la distribution SUSE
zip
- Compresse un fichier
Commandes ksh
Liste des commandes Bash compatibles ksh.
Commandes d'aide
[modifier | modifier le wikicode]man
: Manual - Obtenir le manuel d'une commande.
Écran
[modifier | modifier le wikicode]clear
: efface le contenu affiché à l'écran.more
: Affiche le contenu d'un fichier texte, page par page (la page correspond à la taille du terminal).
Système de fichiers
[modifier | modifier le wikicode]cd
: Change Directory - permet de se déplacer dans le système de fichiers.cp
: CoPy - Copie un fichier ou copie une liste de fichiers dans un autre répertoire en conservant leur nom.ls
: LiSt - Affiche la liste des fichiers dans le dossier courant ou d'un autre dossier.mkdir
: MaKe DIRectory - Crée un ou plusieurs répertoires.mv
: MoVe - Déplace (ou renomme) un fichier, y compris si c'est un répertoire ou déplace une liste de fichiers dans un autre répertoire en conservant leur nom.pwd
: Print Working Directory - permet d'afficher l'endroit où l'on se trouve actuellement dans le système de fichiers.rm
: ReMove - Supprime un/des fichier(s) ou des répertoires.rmdir
: ReMove DIRectory - Supprime un ou plusieurs répertoires s'ils sont vides.touch
: modifie le timestamp d'un fichier existant. S'il n'existe pas un fichier vide est créé.
Recherche
[modifier | modifier le wikicode]egrep
: même commande que grep mais plus riche en possibilités.find
: Recherche récursive, à partir d'un répertoire, de fichiers ayant des caractéristiques données.grep
: Affiche les lignes qui contiennent une expression régulière donnée.
Gestion de texte
[modifier | modifier le wikicode]cat
: CATenate - Concatène des fichiers texte. Peut aussi servir à simplement afficher ou lire un fichier.cut
: Supprime une partie des lignes d'un fichier selon un critère.echo
: Affiche une ligne de texte donnée en paramètre.expr
: Évalue une expression (mathématique ou sur une chaîne de caractères)head
: Affiche les premières lignes d'un fichier (Voir tail).join
: Fusionne les lignes de deux fichiers contenant un ou plusieurs champs identiques.read
: Lit une chaîne de caractères à partir de l'entrée standard.sed
: Stream EDitor - Effectue des transformations sur un flux de texte.sort
: Trie les lignes d'un texte selon l'ordre alphabétique ou numérique.tail
: Affiche les dernières lignes d'un fichier (Voir head).
Permissions
[modifier | modifier le wikicode]chmod
: CHange MODes - Change les permissions en lecture, écriture et/ou exécution d'un fichier.chown
: CHange OWNer - Change le propriétaire, et éventuellement le groupe propriétaire d'un fichier.
Processus
[modifier | modifier le wikicode]ps
: Process Status - Affiche les processus en cours d'exécution.kill
: Envoyer un message à un processus donné, généralement pour y mettre fin.
Gestion de disques
[modifier | modifier le wikicode]mount
: permet de monter un système de fichier.umount
: permet de démonter un système de fichier.
Problèmes connus
Messages d'erreur
[modifier | modifier le wikicode]bad interpreter no such file or directory
[modifier | modifier le wikicode]Les fichiers qui transitent par Windows peuvent ne plus être lisibles par Unix :
sed -i -e 's/\r$//' mon_script.sh ./mon_script.sh
command not found
[modifier | modifier le wikicode]Quand on assigne une variable, il ne faut pas d'espace autour du "=".
Bonnes pratiques
[modifier | modifier le wikicode]
GFDL | Vous avez la permission de copier, distribuer et/ou modifier ce document selon les termes de la licence de documentation libre GNU, version 1.2 ou plus récente publiée par la Free Software Foundation ; sans sections inaltérables, sans texte de première page de couverture et sans texte de dernière page de couverture. |