dernière modification : 2023

Script shell

1. Le principe

Script est synonyme de programme interprété. C’est un fichier texte doté de l’attribut x d’exécution (que l’on positionne avec chmod), contenant des instructions destinées à être lues par l’interpréteur indiqué par le shebang (la première ligne commençant par #!).

Exemple de script shell :

$ ll mon_script_shell
-rwxr-xr-x  1 jaclin jaclin 30 16 déc.  19:16 mon_script_shell (1)

$ head -1 mon_script_shell
#!/bin/bash    (2)

$ ./mon_script_shell (3)
1 le script doit posséder l’attribut x
2 son shebang indique que c’est un script bash
3 on le lance comme ça

Cette dernière instruction consiste :

  1. à lancer l’interpréteur référencé dans le shebang, donc ici /bin/bash

  2. lui envoyer les lignes suivantes sur stdin.

Par conséquent, l’exécution :

$ ./mon_script_shell

est équivalent à

$ /bin/bash < ./mon_script_shell

Le script est lancé par ./mon_script_shell parce qu’il se trouve dans le répertoire courant, mais de manière générale, on doit indiquer son chemin (absolu ou relatif). Pour s’affranchir de cette contrainte (c’est-à-dire lancer le script comme une commande Unix quelconque avec son petit nom), il suffit de le déposer dans l’un des répertoires composant le PATH. Pour cela :

  • regarder si le PATH contient un répertoire nous appartenant

  • si oui, y déposer le script

$ echo $PATH
/users/jaclin/.local/bin:/usr/local/bin:/usr/bin:/bin

Ici oui, /users/jaclin/.local/bin est un répertoire personnel, il suffit donc d’y mettre le script :

$ mv mon_script_shell /users/jaclin/.local/bin

ce qui permet maintenant d’écrire, de n’importe où :

$ mon_script_shell f1 f2 f3
  • si non :

    1. créer un répertoire

    2. l’ajouter au PATH (la position dans le PATH est importante), et faire en sorte que cet ajout soit permanent

    3. y déposer le script

S’il n’y a pas de répertoire personnel dans le PATH, on le crée et on y dépose le script :

$ mkdir ~/bin
$ mv mon_script_shell ~/bin

0n insère ce nouveau répertoire dans le PATH :

$ PATH=~/bin:$PATH

et on rend cette modification permanente, en l’inscrivant dans notre .bashrc :

$ echo 'PATH=~/bin:$PATH' >> ~/.bashrc     # programme l'ajout pour chaque session

Grace aux liens symboliques, on peut éviter de déplacer la commande que l’on veut pouvoir lancer de n’importe où :

$ ln -s mon_script_shell ~/bin

2. Script élémentaire

Dans sa version la plus simple, un script est un fichier qui enchaîne l’exécution de plusieurs commandes :

fichier moncd
#!/bin/bash

echo "le répertoire courant est `pwd`"
echo "on le change en $1"
cd $1
echo "le répertoire courant est maintenant `pwd`"

$1 représente le 1er argument de la ligne de commande, $2 représenterait le 2ème, etc., et $* tous les arguments.

3. Script plus évolué

Il existe aussi les structures de contrôle classiques :

  • if …​ then …​ else…​ fi

  • for …​ do …​ done

  • while …​ do …​ done

  • etc.

Par exemple ici, les données sont lues sur stdin (read) :

home.sh
#!/bin/bash

echo -n "Enter a user name : "
read name
if grep ^$name: /etc/passwd > /dev/null
then
        echo -n "$name has an account on this host, its homedir is "
        awk 'BEGIN { FS=":" } '/^$name:/' {print $6}' /etc/passwd
else
        echo "$name doesn't have an account on this host"
fi

ce qui donne :

$ ./home.sh
Enter a user name : root
root has an account on this host, its homedir is /root

Mieux, on peut lire chaque ligne arrivant sur stdin (while …​ do …​ done) :

home.sh
#!/bin/bash

while read name
do
  if grep ^$name: /etc/passwd > /dev/null
  then
    echo -n "$name has an account on this host, its homedir is "
    awk 'BEGIN { FS=":" } '/^$name:/' {print $6}' /etc/passwd
  else
    echo "$name doesn't have an account on this host"
  fi
done

ce qui donne un filtre utilisable par exemple comme :

$ sed 's/:.*//' /etc/group | home.sh

4. Conclusion

Pour faire des choses simples, comme enchaîner des commandes, le développement de scripts shell est pertinent : le langage est stable et universel, la syntaxe est simple, la mise au point est rapide.