Projet

Général

Profil

Petit precis de shell » Historique » Version 12

« Précédent - Version 12/61 (diff) - Suivant » - Version actuelle
Julien Enselme, 10/08/2013 11:47
itération : rédaction


{{toc}}

Le shell est un langage assez particulier qu'on ne connait pas forcément en arrivant à centrale et qu'on a pas forcément l'occasion de beaucoup pratiquer. Le but de ce document est de rappeler les quelques bases du langage et de fournir quelques solutions standard à des problèmes courants afin que le nouveau membre du club Drupal ne soit pas désemparé et puisse comprendre les scripts. Il ne se veut en aucun cas un cours/tuto complet et exhaustif.

h1. Quelques rappels d'Unix

Le langage shell est le langage de script qui vient par défaut avec tous les Unix. En effet, même si désormais d'autres interpréteurs plus modernes sont désormais répandus (bash, csh, zsh, etc.), ils ont tous conservé la compatibilité avec le shell.

Comme pour la plupart des langages de script, il existe deux façons d'exécuter des instructions shell :

  • directement dans l'interpréteur
  • dans un script shell

Pour lancer un interpréteur shell, rien de plus simple : lancer un terminal (graphique ou tty). Et oui, le shell comprend toutes les commandes Unix que vous avez vues en début d'année (pwd, cd, cp). Vous pouvez donc les réutiliser telles quelles dans vos scripts et utiliser son bon terminal pour faire des boucles, des conditions et j'en passe.

h1. Les bases du shell

Il est très important de comprendre et de garder à l'esprit qu'en shell tout est :

  • chaîne de caractères (y compris les nombres) ! Entrez @echo 1 + 1@ dans le terminal pour vous en convaincre.
  • commande et que donc elles peuvent prendre des arguments (cela s'éclaircira plus tard)

h2. Syntaxe de base

Les commandes s'écrivent soit :

  • les unes à la suite des autres séparées par ; (peu recommandé)
  • séparées les unes des autres par un saut de ligne

Chaque commande peut prendre des arguments de deux types :

  • les arguments courts (l, r, h pour @ls@ par exemple) qui sont passés comme suit : @CMD -ARG@
  • les arguments longs (recursive pour @rsync@ par exemple) qui se passent comme ceci : @CMD --ARGUMENT@

Il est évidement possible de passer plusieurs arguments à une même commande.

Certains arguments existent sous une forme courte et une forme longue. Consulter le manuel de la commande pour plus de détails. Le manuel contient également la liste complète des arguments supportés par une commande.

Certains commandes ne respectent pas la convention énoncée ce-dessus. Leurs arguments long se passent avec un seul - (find en est un exemple)

h2. Valeurs de retour des commandes et exception

Une fois qu'une commande s'est exécutée, elle renvoie une valeur de retour afin "d'informer" l'utilisateur. Cette valeur permet en effet de savoir si la commande s'est exécutée correctement. Voici les valeurs de retour possibles et leur signification :

  • 0 : tout va bien
  • 1 : erreur
  • 2 : erreur grave

Vous pouvez vous aussi utiliser ces valeurs de retour. Par défaut, un script qui se complète correctement retourne 0. Mais vous pouvez (par exemple si un utilisateur tente d'exécuter un script qui nécessite un argument sans) retourner un autre code d'erreur avec la commande @exit@. Il suffit de lui passer le code qu'elle doit retourner. Votre script s'arrêtera alors avec le code d'erreur spécifié.

h2. Conditions et itérations

h3. Conditions if … else …

La structure générale d'une condition est la suivante :

if QQC
then
CMDS
else
CMDS
fi

Le @else@ est facultatif. Il est aussi possible de regrouper @if@ et @then@ en une seule ligne comme ceci : @if QQC ; then@.

La question que vous devriez avoir est que mettre à la place de @QQC@. Il y a deux possibilités :

  • la fonction @test@
  • une commande

h4. La fonction test

Dans toute la suite, il faudra faire très attention aux espaces

La fonction @test@ s'utilise en général comme suit : @if [ ARGS ]@

IMPORTANT : La syntaxe @if ARGS @ n'est valide qu'avec bash. Voir Différences notables avec bash

Pour faire un test, il suffit ensuite de passer les bons arguments à la commande. Par exemple, pour tester si une chaîne est vide : @if [ -z $chaine ]. Si l’argument a besoin de deux paramètres pour fonctionner, mettre un paramètre de chaque côté de celui-ci. Par exemple, pour faire un test d’égalité de chaîne de caractères : @CHAINE1 = CHAINE2@.

On peut aussi combiner les arguments avec des ET et des OU avec les options @-a@ et @-o@. Le caractère "!" permet de faire une négation.

Voir ci-dessous pour la liste complète.

En shell, tout est chaîne de caractère. Bien faire attention au type que l’on veut tester (chaîne ou nombre)

h5. Tests sur les chaînes de caractères

|. Argument |. Signification |
| = | égalité |
| -z | chaîne vide |
| -n | chaîne non vide |

h5. Tests sur les nombres

|. Argument |. Signification |
| -eq | égalité |
| -ne | non égalité |
| -lt | strictement plus petit |
| -gt | strictement plus grand |
| -ge | plus grand ou égal |
| -le | plus petit ou égal |

h4. Test avec une commande

Comme indiqué précédemment, une commande qui s’exécute correctement est considérée comme vrai. Ainsi, il est tout a fait possible, par exemple, pour savoir si on arrive à se connecter à un serveur mysql de faire simplement : @if mysql -h HOST -u asso -pTATA@.

Parfois vous pourrez rencontrer des problèmes. Pensez alors à donner cette commande en argument à la fonction test

h3. Boucles while/until

La structure générale est la suivante :

while QQC
do
CMD
done

Il est possible de regrouper @while QQC@ et le @do@ en @while QQC ; do@. Le QQC peut être remplacer par exactement les mêmes choses que pour la condition. Se référer à cette section pour les précisions.

Le shell propose également le mot clé @until QQC@ qui fait une action jusqu’à ce que QQC soit réalisé.

h3. Boucle for

L’utilisation de la boucle for en shell ressemble à celle de python. La structure générale est la suivante :

for var in CMD
do
CMD
done

La variable var va alors prendre une à une les valeurs données par CMD. Par exemple, @for file in ls@ la variable var va prendre tour à tour le nom de tous les fichiers et dossiers donnés par la commande @ls@.

Vous pouvez également utiliser for pour boucler d’un nombre à un autre avec la syntaxe : @for i in {2..9}@

h1. Les fonctions

Parler de @local@ pour que les arguments soient internes à la fonction.

h1. Les redirections de flux

, >>, 2>&1, &>, |&

h1. Paramètres de scripts

  • $1, $2, …, $9
  • $#
  • $*
  • $?

h1. Exécuter une commande

`` vs $(…)

h1. Importer une configuration

@. config-file.sh@

h1. Mode debug

@sh -x SCRIPT@

h1. Différences notables avec bash

h1. Divers

h2. Différences entre la sortie de ls et de find

ls : chemin relatif ; find auei : chemin absolu