Bash

-------------------------------
Linux : Le scripting bash
Niveau : débutant linux
Prérequis : bases du shell
-------------------------------

Voici le sommaire de cet article :

-----------------------------------------------------------------------

 

1) Introduction

 

Les scripts peuvent servir à créer des routines pour faciliter l'usage de Linux. Il est important de connaître la programmation shell car elle est pas mal utilisée dans le système Unix.

Avantages :

- Bash est un logiciel libre
- Les scripts bash sont  interprétés (pas besoin de recompiler à chaque changement)

Inconvénients :

- Documentation longue (+ de 4000 lignes pour man bash) et difficile d'accès pour les débutants.
- Une syntaxe un peu ardue
- Debuggage pas toujours évident du aux messages d'erreurs pas terrible ou inexistants.

Un script bash (extension .sh) est un script qui est interprété par le bash (dans /bin/bash). Pour spécifier au shell ou se trouve et quel est l'interpréteur on place au début du script :  «#!/bin/bash». Pour pouvoir rendre le script exécutable on devra faire  chmod +x monScript

 

2) Variables et évaluation

Il n'existe QU'UN SEUL TYPE de variable : les chaines de caractères. Pour définir une variable on utilise la syntaxe suivante :

$ var='ma variable'

Remarquez qu'il n'y a pas d'espace de chaque coté du signe égal et les guillemets simples (quotes). On aurait pu s'en passer si on avait eu une variable ne contenant pas d'espace. Pour afficher le contenu d'une variable, on dispose de la commande echo.

$ echo $var

ma variable

Le dollar sert à indiquer que l'on veut afficher le contenu de la variable var. Si on veut afficher une variable qui n'existe pas cela ne produira pas d'erreur et affichera une chaîne de caractères vide (i.e rien) Cela présente un inconvénient car si on s'est trompé dans le nom du variable on ne le voit pas forcement ce qui complique le debuggage. On peut être amener à utiliser les accolades {}. Elles servent à délimiter une variable quand celle ci est collée à une chaîne de caractères.

numero=0

echo "c'est bientôt le numéro ${numero}2 de l'ezine espionet"

c'est bientôt le numéro 02 de l'ezine espionet.

Remarquez l'utilisation des doubles quotes qui servent à pouvoir utiliser des quotes dans la phrase.

 

3) Evaluation

 

Les quotes ou double quotes n'ont pas le même sens. Le premier empêche l'évaluation :

$ x=toto

$ echo 'mon ami est $x'

mon ami est $x

$ echo "mon ami est $x"

mon ami est toto

 

4) Découpage de chemins

 

Les commandes dirname et basename permettent de récupérer séparément répertoires et fichiers :

$ dirname /root/tata/toto.txt

/root/tata

$ basename /root/tata/toto

toto.txt

 

5) Evaluation de commandes

 

Pour évaluer des commandes on peut utiliser les backquotes `` ou alors $()

$ rep=`dirname /root/tata/toto.txt`

echo $rep

/root/tata

$ rep=$(dirname /root/tata/toto.txt)

echo $rep

/root/tata

On peut bien évidemment mettre des commandes shell de 3 lignes à évaluer. On utilisera de préférence la méthode avec les parenthèses car elle permet de ne pas confondre les backquotes avec les quotes.

 

6) Découpage de chaines

 

C'est la que la syntaxe ne devient pas très jolie :). La notation ## permet d'éliminer la plus longue chaîne en correspondance avec le motif :

$ var='zogabuzomeu'

$ echo ${var##*zo}

meu

On élimine ici la plus longue chaîne de la variable var finissant par zo (le * permet de dire qu'il y a quelque chose qu'on connaît pas avant). De même # permet d'enlever la chaîne la plus petite :

$ echo${var#*zo}

gabuzomeu

 

Les notation %% et % permettent  d'éliminer la fin d'une chaîne On peut ainsi supprimer des extensions :

$ var = 'toto.tar.gz'

$ echo ${var%.*}

toto.tar

$ echo ${var%%.*}

toto

 

7) Exécution conditionnelle

 

On peut maintenant passer à la programmation à proprement parler.  

Commençons par la structure if :

if [ condition ]

then

      action

fi

 

Attention à bien respecter les espaces pour la première ligne !! L'indentation n'est pas obligatoire mais simplement conseillée.

 

On peut ensuite incorporer else et else if :

if [ condtion ]

then

      action1

else

      action2

fi

 

 

if [ condtion ]

then

      action1

Else if [condition]

      action2

Else if [condition]

      action3

fi

 

 

8) Opérateurs de comparaison

 

Opérateurs sur des fichiers

 

Opérateur         Description

 

-e filename       vrai si filename existe

-d filename       vrai si filename est un répertoire

-f filename       vrai si filename est un fichier symbolique

-L filename       vrai si filename est un lien symbolique

-r filename       vrai si filename est lisible

-w filename       vrai si filename est modifiable

-x filename       vrai si filename est exécutable

file1 -nt file2       vrai si file1 est + récent que file2

file1 -ot file2       vrai si file1 est + ancien que file2

 

 

Opérateurs sur les chaines

 

Opérateur         Description

 

-z chaîne         vrai si chaîne est vide

-n chaîne         vrai si chaîne est non vide

chaine1 = chaine2      vrai si deux chaines sont égales

chaine1 != chaine2      vrai si deux chaines sont différentes

 

Opérateurs de comparaison numérique

 

Opérateur de comparaison numérique

 

Opérateur         Description

 

num1 -eq num2        vrai si égalité

num1 -ne num2        vrai si inégalité

num1 -lt num2        vrai si inférieur

num1 -le num2        vrai si inférieur ou égal

num1 -gt num2        vrai si supérieur

num1 -ge num2        vrai si supérieur ou égal

 

Il faut noter cependant plusieurs choses importantes :

- Toutes les variables sont des chaines de caractères. La valeur est juste convertie en nombre pour les opérateurs de conversion numérique

- Il est nécessaire d'entourer les variables de " dans les comparaisons. On ne peut pas écrire if [$var = "toto tata"] car cela déclenche une erreur car $var contient plusieurs mots. Il faut écrire: if [«$var" = "toto tata"]

 

9) Arguments de la ligne de commande

Lorsqu'on utilise un script on lui pass bien souvent des arguments. Pour récupère les arguments on utilise la notation $ suivi d'un nombre.

$0 correspond au nom du script

$1 correspond au premier argument

$2 correspond au deuxième argument,...

$# correspond au nombre d'arguments

$* correspond à tous les arguments

 

Si on a un script qui s'appelle mesargs.sh  

Avec dedans :

echo 'prog : ' $0

echo 'arg1 : ' $1

echo 'arg2 : ' $2

echo 'arg3 : ' $3

echo 'nombre args : '$#

echo 'tous les args : ' $*

 

$ mesargs.sh un deux

prog : ./mesargs.sh

arg1 : un

arg2 : deux

arg3 :

nombre args : 2

tous les args : un deux

 

 

10) Autres structures de contrôle

-La boucle for

ex :

for x in un deux trois

do

      echo x

done

 

affiche :

un

deux

trois

 

Remarque : l'instruction de fin aurait du être od (comme fi pour if) mais celle ci existait déjà.

 

- L'instruction case

 

case "$x" in

      go)

            echo "starting ...."

      ;;

      stop)

            echo "stopping ...."

      ;;

      *)

            echo "$0 go ou $0 stop"

      ;;

esac

 

Remarque : notez l'utilisation des ;; pour finir les blocs d'instruction et esac qui est la palindrome de case.

 

11) Définition de fonctions

 

C'est une syntaxe (pour une fois) :

 

mafct() {

      echo "c'est ma fonction"

}

 

 

On appelle la fonction comme ça : «mafct». Ce qui nous donne : " c'est ma fonction "

 

12) Exemples de scripts simples

Script qui affiche le contenu d'un fichier compresse.

 

tarview() {

      echo -n " Affichage du contenu de l'archive 1"

      case "{1##*.}" in

            tar)

                  echo "tar compresse"

                  tar tvf $1

            ;;

            tgz

                  echo "tar compresse gzip"

                  tar tzvf

            ;;

            bz2)

                  echo "tar compresse bzip2"

                  cat $1 | bzip2 -d | tar tvf -

            ;;

            *)

                  echo "Erreur, ce n'est pas une archive"

            ;;

      esac

}

 

 

Script qui affiche la liste des utilisateurs réels avec leur UID correspondant ( UID > 500 )

 

a=$(cut /etc/passwd  -d : -f 1,4)

echo "Les utilisateurs réels sont :"

for l in $a

do

    uid=${l##*:}

    user=${l%:*}

    if [ $uid -ge 500 ]

    then

      echo "$user"

    fi

done

 

13) Conclusion

 

Voilà, j'espère que cette introduction vous aura plus. Ce sont les bases qui vous permettront de comprendre mieux comment fonctionnent les scripts Unix. Je vous conseille vivement d'aller jeter un coup d'oeil dans ces scripts ( un petit find / -name *.sh vous permettra d'en trouver quelques uns) Par exemple ( je sais pas si c'est dans le même rep sous toutes distrib) il y a /lib/rcscripts/sh/rc-services.sh qui vous montre qu'on peut faire des choses assez complexes.

 

Remerciements : Manu pour son cours :')   -->  http://www-gtr.iutv.univ-paris13.fr/Equipe/viennet

 

-----------------------------------------------------------------------

 

Fafounet  
http://caddie.scooba.org 

Pour me contacter :

Fafounet : fabienrenaud@hotmail.com