dimanche 17 novembre 2013

introduction au language shell (bash)

Bash

Sous linux vous entendrez souvent parler de terminal, en mode graphique sous kde par exemple cela peut etre assimile à la petite tv noire à gauche de la barre des taches.

En realite à partir du terminal l'utilisateur peut dialoguer avec le systeme via un interpreteur de commandes shell.

Il existe plusieurs varietes de shell, celui par defaut sous linux est bash (bourne again shell), il est tres pratique et permet de realiser des scripts qui vous faciliteront la vie.

Nous nous interessons ici à l'aspect langage de programmation de bash, l'aspect "lignes de commandes tapees au prompt" est traite dans Commandes utiles
1. Conventions :

Un script bash est un fichier texte, qui commence toujours par #!/bin/bash ou #!/bin/sh, il doit etre rendu executable pour pouvoir s'executer

Dans ce fichier on definit, les comandes selon l'odre dans lequel on souhaite qu'elles s'executent. Par exemple si je souhaite, creer puis supprimer un fichier, je dois creer un fichier mon_script.sh, dans lequel je mets les lignes suivantes :
#!/bin/bash
touch fichier.txt
rm fichier.txt

je le sauve et je le rends executable (pour moi) par :
chmod u+x mon_script.sh

Plus tard pour l'executer ce sera :
/le_chemin_vers/mon_script.sh

Par defaut mon_script.sh, utilise le PATH de mon environnement, c'est à dire l'ensemble des repertoires susceptibles de contenir des executables : echo $PATH permet d'en avoir une idee.

Si je souhaite inclure /usr/mon_rep/bin dans la recherche d'executable, il me suffit de modifier mon_script.sh comme ceci :
#!/bin/bash
PATH=$PATH:/usr/mon_rep/bin
touch fichier.txt
rm fichier.txt

Si je souhaite restreindre la recherche d'executable à un certain nombre de repertoire :
#!/bin/bash
PATH=/urs/bin:/usr/mon_rep/bin
touch fichier.txt
rm fichier.txt

On peut definir des variables locales dans le script par MA_VARIABLE = 'moi' ou MA_VARIABLE = $0. Pour les manipuler il faut les prefixer du symbole $, exemple :
#!/bin/bash
a="mozilla"
b="$a.tgz"
tar -xzvf $b
2. Les parametres :

Les scripts bash, acceptent des parametres, on peut recuperer leurs valeurs dans le script par :

*

$0 pour le premier parametre (qui correspond au nom du script lance) $1 pour le second (= le premier argument), $2 pour le troisieme(=le deuxieme argument) ...
*

$# a pour valeur le nombre total de parametres ($0 compris) passes au script
*

$? a pour valeur le code de retour de la derniere commande executee dans le shell
*

$@ pour recuperer la concatenation de tous les parametres, en les separant par un espace

3. Les Metacaracteres, Operateurs et commandes speciales :

*

* designe une chaine de caracteres quelconque ne commencant pas par un metacaractere .
*

? designe un caractere quelconque.
*

# precede une ligne de commentaires.
*

[aA] designe les caracteres A et a
*

[0-9a-zA-Z] designe un caractere alphanumerique quelconque.
*

[!0-9] designe l'ensemble des caracteres qui ne sont pas des chiffres.
*

; separe deux commandes (ou plus) situees sur une meme ligne.
*

&&

Dans l'exemple : commande1 && commande2, la commande2 ne sera executee que si la commande1 se termine par un succes.
*

||

Dans l'exemple : commande1 || commande2, la commande2 ne sera executee que si la commande1 se termine par un echec.
*

|

Dans l'exemple : commande1 | commande2, l'entree de la commande2 est la sortie de la commande1
*

' ' delimitent une chaine de caracteres contenant des espaces. A l'interieur, tous les metacaracteres perdent leur signification.
*

" " delimitent une chaine de caracteres contenant des espaces. A l'interieur, tous les metacaracteres perdent leur signification, à l'exception des metacaracteres `, $ et \
*

` `(accent grave) ou $( ) "capture" la sortie standard pour former un nouveau parametre ou une nouvelle commande.
*

$ retourne le contenu de la variable qui suit (il ne doit pas y avoir d'espace entre le metacaractere $ et le nom de la variable).
*

$((calcul_arithmetique)) retourne le resultat du calcul passe entre les deux parentheses. C'est donc une alternative à expr qui est incluse dans Bash.
*

\ protege le caractere qui suit, que ce soit un caractere normal ou un metacaractere du shell (sauf à l'interieur d'une chaine delimitee par des .
*

( et ) permettent de regrouper un ensemble de commandes et de les executer dans un "shell fils"
*

exit Vous permet de sortir d'un programme en cours d'execution.

4. Les structures de controles :

Comme dans tout langage de programmation, avec bash il est possible de casser la sequence d'execution des commandes, en utilisant les structures de controles habituelles.
4.1 IF :
La syntaxe
if condition_1; then
commandes1
elif condition_2; then
commandes2
else
commandes3
fi
Un exemple :
if test $# -ne i; then
echo "erreur de syntaxe"
else
latex $1
dvips -o $1.dvi
fi
4.2 FOR :
Deux syntaxes possibles :
for variable in liste_de_cas do
commandes
done

for (( expr1 ; expr2 ; expr3 )) do
commandes
done
Un exemple pour chacun :
for FICHIER in 'ls *.c'
do
chmod go-r $FICHIER
done

for (( i=0 ; i<5 ; i++ ))
do
echo "Valeur de i = $i"
done
4.3 WHILE :
while condition do
commandes
done
4.4 UNTIL :
until condition do
commandes
done
4.5 CASE :
case variable in
cas1)
commande1
;;
cas2)
commande2
;;
*)
commande_par_defaut
;;
esac

cas1 et cas2 etant des chaine de caracteres.
5. Les Conditions :

Il y'a deux facons de realiser des conditions, par exemple si je veux traduire l'algorithme suivant :
si mon_fichier existe alors
afficher "il existe"
sinon
afficher "il n'existe pas"

Je peux ecrire :
if test -f mon_fichier; then
echo "il existe"
else
echo "il n'existe pas"
fi

Ou tout simplement :
if [ -f mon_fichier ]; then
echo "il existe"
else
echo "il n'existe pas"
fi

Quelques comparaisons utiles :
-f teste l'existence d'un fichier
-g teste l'existence d'un fichier le l'existence du GID bit
-k idem mais avec le sticky bit
-u idem mais avec l'UID bit
-d teste l'existence d'un repertoire
-x teste si le fichier existe et est executable
-r teste si le fichier existe et est ouvert en lecture
-w teste si le fichier existe et ouvert en ecriture
-s teste si le fichier existe et a une taille superieur à 0 octet
-L teste si le fichier existe et est un lien symbolique


ATTENTION :

Cela peut paraitre surprenant, mais il n'existe pas de type Booleen ( True/False ou encore 0/1 ) en Bash, ni d'autres types d'ailleurs, car Bash est un langage non-type. Ceci etant, les conditions, sous leur forme booleenne, n'existent donc pas à proprement parler. Dans ce document, nous avons tout de meme utilise le mot 'condition' pour ne pas perturber le lecteur, mais sachez que ce sont en fait des 'commandes' qui jouent ce role. Je m'explique, Bash considere qu'une commande s'est bien deroule lorsqu'elle recoit comme valeur de sortie '0' (zero), tout autre valeur correspondant à une execution non reussi (entierement ou partiellement). Donc, si, dans la structure de commande, la commande qui joue le role de condition renvoie '0', alors cela correspond à un True dans le type Booleen, et vice-versa. Sachez donc, qu'au lieu d'utiliser une 'condition' en utilisant la commande test ( comme vu ci-dessus ), vous pouvez aussi utiliser le code de sortie d'une commande à la place.
6. Les fonctions :

On peut definir des fonctions en bash cela peut etre tres utile pour structurer ses programmes, la syntaxe est la suivante :
fonction() {
corps
}

Pour appeler la fonction dans le script se sera :
fonction param1 param2 param3 ...

a l'interieur du corps de la fonction, les parametres sont disponibles dans les variables $0, $1, $2 ... Le nombre de parametres etant toujours $#.
Un exemple :
affTABLE1 () {
i=$2
while [ $i -le $3 ] ; do
echo -e "$1 * $i \t = `expr $1 \* $i`"
i=`expr $i + 1`
done
}
#On redirige les parametres du script vers la fonction
affTABLE1 $1 $2 $3

Ne pas oublier qu'une variable utilisee à l'interieur d'une fonction est globale! Pour eviter ce phenomene, il faut rajouter local à la declaration de la variable :
local MA_VARIABLE

Une fonction se termine soit apres l'execution de la derniere commande situee avant l'accolade fermante, auquel cas le code de retour est celui de cette derniere commande, soit apres execution d'une commande return n (1,2,3 ...) auquel cas le code de retour est l'argument n de la commande return (ou 0 si cet argument est absent).

Dans les deux cas, le code de retour de la fonction est affecte au parametre $? du shell courant.
7. La commande expr :

expr vient de "expression". Cette commande permet d'effectuer des operations arithmetiques et logiques, ainsi que des operations sur les chaines de caracteres plus sophistiquees que la simple concatenation, elle renvoie le resultat de ces operations sur la sortie standard. Le resultat est donc recuperable entre ``(accents graves).
Un exemple :
a=2
b=3
a=`expr $b % $a`
echo $a

Ce script affiche 1. La liste des operations est la suivantes :

*

+ (addition), - (soustraction), * (multiplication), / (quotient de la division entiere), % (reste de la division entiere), si argument1 et argument2 ont comme valeurs des chaines de caracteres constituees uniquement de chiffres (et donc interpretables en tant qu'entiers).
*

= (egalite), != (difference), >, >=, < , <= ,(comparaisons), si argument1 et argument2 ont comme valeurs des chaines de caracteres quelconques (attention : pour les operations de comparaison, la valeur VRAI est codee par 1 et la valeur FAUX par 0, comme en C).



_________________
Image

VOUS AVEZ AIMÉ CET ARTICLE ?

0 commentaires:

Enregistrer un commentaire