Bash

Aller à : navigation, rechercher

Bash est un interpréteur de commandes Unix (shell) écrit pour le projet GNU. Son nom est un acronyme pour Bourne-again shell — un calembour (Bourne again / born again) sur le Bourne shell (sh), qui fut un important shell Unix, plus ancien. Le Bourne shell était le shell distribué avec Version 7 Unix, circa 1978. Le Bourne shell original fut écrit par Stephen Bourne, alors chercheur aux Bell Labs. Le Bash shell fut écrit en 1987 par Brian Fox. En 1990, Chet Ramey devint le premier mainteneur. Bash est le shell par defaut sur la plupart des systèmes Linux.

Points culminants de syntaxe de Bash

La syntaxe de commande de Bash est un surensemble de celle du shell Bourne. Les spécifications définitives de la syntaxe de commande de bash sont le manuel de référence de Bash distribué par le projet GNU. Cette section souligne certains des dispositifs uniques de la syntaxe de Bash.

La grande majorité des scrpits du shell Bourne peut être exécutée sans changement par bash excepté les scripts de shell Bourne qui s'avèrent justement mettre en référence une variable spéciale de Bourne ou employer une commande interne de Bourne. La syntaxe de commande de bash inclut des idées tirées de Korn shell (ksh) et de C shell (csh), comme l'édition de commande-ligne, l'historique de commande, la pile de répertoire, les variables $RANDOM et $PPID , et la syntaxe de substitution de commandes POSIX : $(...). Quand on l'utilise en interpréteur de commande interactif, Bash fournit l'autocomplémentation des noms de programmes, fichiers, variables, partiellement écrits, quand l'utilisateur appuie sur la touche TAB.

La syntaxe de Bash a beaucoup d'extensions dont le shell Bourne manque. Plusieurs de ces extensions sont énumérées ici.

Mathématiques entières

Une limitation importante du shell Bourne est qu'il ne peut pas exécuter de calculs de nombre entier sans faire appel à un processus externe. Bash peut exécuter des calculs de nombre entier de manière interne en utilisant la commande ((...)) et la syntaxe variable de $[...], comme suit :

VAR=55             # Assigne l'entier 55 à la variable VAR.
((VAR = VAR + 1))  # Ajoute un à la variable VAR.  Noter l'absence du caractère '$' .
((++VAR))          # Un autre moyen d'ajouter un à VAR.  C-style pre-increment.
((VAR++))          # Un autre moyen d'ajouter un à  VAR.   C-style post-increment.
echo $[VAR * 22]   # Multiplie VAR par 22 et substitute le résultat dans la commande.
echo $((VAR * 22)) # Un autre moyen de faire comme ci-dessus.

La commande ((...)) peut également être employée dans des instructions conditionnelles, parce que son code retour exit status est 0 ou 1 selon si la condition est vraie ou fausse :

if ((VAR == Y * 3 + X * 2))
then
        echo Yes
fi

((Z > 23)) && echo Yes

La commande ((...)) supporte les opérateurs de relation suivants : '==', '!=', '>', '<', '>=', et '<='.

Bash ne peut pas exécuter des calculs de virgule flottante en interne (floating point) . Les seuls interpréteurs de commande Unix qui le peuvent sont Korn Shell (1993 version) et zsh (à compter de version 4.0).

Redirection des entrées/sorties (I/O redirection)

Bash a plusieurs syntaxes de redirection d'entrée-sortie dont le shell Bourne traditionnel manque. Bash peut réorienter la sortie standard et la sortie d'erreur standard en même temps en utilisant cette syntaxe:

command &> file

ce qui est plus simple à écrire que l'équivalent de shell Bourne, "command > file 2>&1". Bash, depuis la version 2.05b, peut rediriger l'entrée standard depuis une chaîne en utilisant la syntaxe suivante (parfois appelée "here strings" (ficelle?)):

command <<< "chaîne à lire comme entrée standard "

Si la chaîne contient des caractères espace whitespace (computer science),elle doit être mise entre quotes (guillemets droits).

Exemple: Rediriger la sortie standard (stdout) vers un fichier, écrire des données, fermer le fichier, remettre stdout

# faire de Filedescriptor(FD) 6 une copie de stdout (FD 1)
exec 6>&1
# ouvrir le fichier "test.data" pour écrire
exec 1>test.data
# produire du contenu
echo "data:data:data"
# fermer le fichier "test.data"
exec 1>&-
# faire de stdout une copie de FD 6 (reset stdout)
exec 1>&6
# fermer FD6
exec 6>&-

Ouvrir et fermer des fichiers

# ouvrir le fichier test.data en lecture
exec 6<test.data
# le lire jusqu'à fin de fichier
while read -u 6 dta
do
  echo "$dta" 
done
# fermer test.data
exec 6<&-

Capturer la sortie de commandes externes

 # executer 'find' et mettre le résultat dans VAR
 # rechercher les noms de fichiers se terminant par la lettre "h"
 VAR=$(find . -name "*h")

Expressions régulières internes

Bash 3.0 supporte les correspondances selon des expressions régulières internes, en utilsant la syntaxe suivante, réminiscente de Perl:

[[ string =~ regex ]]

La syntaxe d'expression régulière est identique à celle documentée par regex (3) cf man page. L'état de sortie de la commande ci-dessus est 0 si regex correspond à la chaîne, 1 sinon. Des sous-expressions parenthèsées dans l'expression régulière sont accessibles en utilisant la vairable shell BASH_REMATCH, comme suit:

if [[ abcfoobarbletch =~ 'foo(bar)bl(.*)' ]]
then
        echo The regex matches!
        echo $BASH_REMATCH      -- outputs: foobarbletch
        echo ${BASH_REMATCH[1]} -- outputs: bar
        echo ${BASH_REMATCH[2]} -- outputs: etch
fi

Cette syntaxe donne une performance supérieure à celle obtenue en faisant appel à un processus distinct pour exécuter une commande grep car l'examen de correspondance de l'expression régulière prend place à l'intérieur du traitement Bash. Si l'expression régulière ou la chaîne contiennent des espaces ou métacaractères (tel que '*' ou '?'), il faut les entourer de quotes.

Échappement avec barre oblique inverse (backslash escapes)

Des mots de la forme $'string' sont traités spécialement. Le mot est remplacé par la chaîne avec les caractères d'échappement à barre oblique inverse remplacés comme spécifié dans le langage de programmation C. Les séquences d'échappement à barre oblique inverse, s'il y en a, sont décodées comme suit:

Échappement avec barre oblique inverse (backslash escapes)
Backslash
Escape
Résulte en ...
\a Un caractère alerte (cloche) (bell)
\b Un caractère d'espacement arrière (backspace)
\e Un caractère d'échappement (escape)
\f Un caractère saut de page (form feed)
\n Un caractère nouvelle ligne (new line)
\r Un caractère de retour de chariot (carriage return)
\t Un caractère de tabulation horizontale
\v Un caractère de tabulation verticale
\\ Un caractère de barre oblique inverse (backslash)
\' Un caractère d'apostrophe (quote)
\nnn Le caractère de huit bits dont la valeur est donnée en octal par les chiffres nnn (un à trois)T
\xHH Le caractère de huit bits dont la valeur est la valeur hexadécimale HH (un ou deux chiffres )
\cx Un caractère control-X

Le résultat obtenu est simplement quoté, comme si le signe du dollar n'avait pas été présent

Une chaîne entre double quote précédée par un signe dollar ($"...")sera traduite selon la localisation courante. Si,la localisation courante est C ou POSIX, le signe dollar est ignoré . Si la chaîne est traduite et remplacée, le remplacment est double quoté.

Scripts de démarrage Bash

Quand Bash démarre, il exécute les commandes d'un ensemble de scripts différents.

Quand Bash est appelé en tant que shell interactif de login, ou en shell non interactif avec l'option --login, il lit et exécute tout d'abord les commandes du fichier /etc/profile,s'il existe. Après avoir lu ce fichier, il regarde ~/.bash_profile, ~/.bash_login, et ~/.profile, dans cet ordre et lit puis exécute les commandes du premier qui existe et est lisible. L'option --noprofile peut être utilisée quand le shell est démarré, pour inhiber ce comportement.

Quand un shell de login se termine, Bash lit et exécute les commdes du fichier ~/.bash_logout, s'il existe.

Quand un shell interactif , qui n'est pas un shell de login, démarre, Bash lit et exécute les commandes de ~/.bashrc, si ce fichier existe. On peut l'empêcher en utilisant l'option --norc.
L'option --rcfile file forcera Bash à lire et exécuter les commandes depuis le fichier file plutôt que depuis ~/.bashrc.

Quand Bash est démarré non interactivement, pour exécuter un script par exemple, il recherche la variable BASH_ENV dans l'environnement, reprend sa valeur si elle apparait là, et utilise la valeur obtenue comme nom d'un fichier à lire et exécuter. Bash se comporte comme si la commande suivante avait été exécutée:

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

mais la valeur de la variable PATH n'est pas utilisée pour chercher le nom de fichier.

Si Bash est appelé avec le nom sh, il essai d'imiter le comportement de démarrage des versions historiques de sh du mieux possible, tout en se conformant au standard POSIX Quand il est appelé en tant que shell interactif de login, ou en shell non interactif avec l'option --login, il lit et exécute tout d'abord les commandes des fichiers /etc/profile et ~/.profile dans cet ordre. L'option --noprofile peut être utilisée quand le shell est démarré, pour inhiber ce comportement. Quand il est appelé comme shell interactif avec le nom sh,Bash regarde la variable ENV, reprend sa valeur si elle apparait là, et utilise la valeur obtenue comme nom d'un fichier à lire et exécuter. Du fait qu'un shell appelé par sh n'essaie pas de lire et exécuter des commandes depuis aucun autre fichier de démarrage, l'option --rcfile est sans effet. Un shell non interactif appelé avec le nom sh n'essaie de lire et exécuter aucun fichier de démarrage. Quand il est appelé avec le nom sh, Bash se met en mode posix après lecture des fichiers de démarrage.

Quand Bash est démarré en mode posix, comme avec l'option --posix sur la ligne de commande, il suit le standard POSIX pour les fichiers de démarrage. Dans ce mode, les shells interactifs évaluent la variable ENV et les commandes sont lues et exécutées depuis le fichier dont le nom résulte de l'évaluation. Aucun autre fichier de démarrage n'est lu.

Bash essaie de déterminer s'il est appelé à partir d'un démon distant (remote shell daemon), le plus souvent rshd. Si Bash détermine qu'il est lancé par rshd, il lit et exécute les commandes depuis ~/.bashrc si ce fichier existe et est lisible. Il ne le fait pas s'il est appelé en tant que sh. L'option --norc peut être utilisée pour emêcher ce comportement et l'option --rcfile peut être utilisée pour forcer la lecture d'un autre fichier, mais en général, rshd n'appelle pas le shell avec ces option ni même ne permet qu'elles soient précisées

Liens externes

Bash guides from the Linux Documentation Project:

Other guides and tutorials: