Bonjour à tous.
Aujourd'hui je vous propose un petit tutoriel sur l'art de réaliser un script.
Avant tout, qu'est ce qu'un script ?
D'après Wikipedia, un script c'est ça :
Un langage de script est un langage de programmation qui permet de manipuler les fonctionnalités d'un système informatique configuré pour fournir à l'interpréteur de ce langage un environnement et une interface qui déterminent les possibilités de celui-ci. Le langage de script peut alors s'affranchir des contraintes de bas niveau — prises en charge par l'intermédiaire de l'interface — et bénéficier d'une syntaxe de haut niveau.
Le langage de script est généralement exécuté à partir de fichiers contenant le code source du programme qui sera interprété. Historiquement ils ont été créés pour raccourcir le processus traditionnel de développement édition-compilation-édition des liens-exécution propre aux langages compilés. Les premiers langages étaient souvent appelés langage de commande ou langage d'enchaînement des travaux (JCL : Job Control Language) car ils permettaient simplement d'automatiser une succession de commandes simples, à la manière d'un « script » de théâtre.
-------------
Pour simplifier, c'est un fichier contenant une suite d'instructions.
À la différence d'un programme, un script n'est pas compilé; il est interprété par un environnement.
Je vous propose dans ce tutoriel quelques pistes sur les scripts shell/bash.
Petit rappel sur les interpreteurs de commandes : http://fr.wikipedia.org/wiki/Shell_Unix
Avant de se lancer dans le script, il faut connaître quelques commandes de base de notre cher terminal.
Pour ça, je vous envoie vers ce tutoriel qui m'a l'air au premier abord assez simple et complet : http://wiki.linux-aide.org/index.php?n=Terminal.PremiersPasAvecLeTerminal
Maintenant que vous êtes prêts, voici le plan que j'ai choisi (très basique cela dit)
I)Présentation générale
II)L'art de scripter
III)Quelques exemples
Allez, c'est parti !
I)Présentation
Voivi un script très basique:
MESSAGE="toto";
affiche() {
cat <<EOT
$MESSAGE
EOT
}
affiche;
exit 0;
----------------
NB_PARAMETRES=$#;
PARAMETRE_1=$1;
affiche_nombre_parametres() {
# Si le nombre de paramètres est plus grand que 1, on affiche la phrase au pluriel
if [ "$NB_PARAMETRES" -gt "1" ] ; then
echo "Vous avez entré $NB_PARAMETRES paramètres.";
else
echo "Vous avez entré $NB_PARAMETRES paramètre.";
fi
}
affiche_premier_parametre() {
affiche_nombre_parametres;
if [ ! -z "$PARAMETRE_1" ] ; then
echo "Le premier paramètre est: $PARAMETRE_1.";
else
echo "Il n'y a pas de paramètre.";
fi
}
affiche_premier_parametre;
echo "tous les paramètres: $*";
exit 0;
Il vous suffit d'enregistrer ces 2 scripts dans un fichier text que vous nommerez avec l'extension .sh (script1.sh et script2.sh par exemple).
Pour les exécuter: sh script1.sh
sh script2.sh param1 param2 etc. # vous pouvez essayer sans paramètre
On commence par le commencement:
Cette ligne précise l'interpréteur de commande à utiliser, selon votre système vous avez le choix entre /bin/sh, /bin/bash, /bin/ksh, etc...
Ici nous nous concentretons sur /bin/sh
Arrivent ensuite les variables:
MESSAGE="toto";
La convention veut qu'on nomme les variables en MAJUSCULE, maisi ça ne vous empêchera pas d'exécuter votre script si vous l'oubliez.
Pour affecter une valeur à une variable, on utilise le signe « = » (/!\il n'y a pas d'espace entre la variable et sa valeur/!\), les valeurs sont en général misent entre double quote « " ».
Je vous ai rédigé une fonction:
affiche() {
[...]
}
« affiche » est le nom de la fonction, les parenthèses « () » sont là pour spécifier qu'il s'agit d'une fonction. Les instruction de cette fonction sont misent entre accolades « { } ».
Vous y mettez ce que vous voulez.
Pour exécuter la fonction, il faut l'appeler à l'interieur du script:
affiche;
Finallement, pour quitter proprement le script, on ajoute la ligne suivante :
exit 0;
Cette ligne permet de renvoyer le code de sortie qui sera présent dans la variable $? (plus d'info sur cette variable dans la suite).
Ça c'était pour le détail du premier script. Script très basique qui ne fait qu'afficher « toto ».
Le second script est lui un peu plus évolué (rassurez-vous, pas beaucoup plus ^^°).
Cette fois-ci, j'ai choisis d'utiliser bash comme interpréteur de commandes, c'était juste pour faire une variante, mais préférez shell.
Dans ce script, j'ai commencé à utiliser les variables particulières, à savoir $#, $* et $1
Ce script contient également quelques tests, histoire de voir à quoi ça ressemble ;-) .
On commence par $#, cette variable contient le nombre de paramètres fournis au script, si par exemple je lance mon script de cette manière :
sh script.sh toto titi tata
$# aura pour valeur 3
$1 contient elle le premier paramètre, à savoir dans notre exemple « toto ».
on peut aller comme ça jusque $9, pour le dixième paramètre, il faudra utiliser une petite astuce que je décrierai plus bas.
$* contient elle la liste de tous les paramètres, toujours dans notre exemple, ça nous donne :
toto titi tata
Ensuite, vous pouvez voir comment ajouter un commentaire dans le script, c'est cette ligne :
« # fonction d'affichage du nombre de paramètres ». Il vous suffit donc de mettre un dièze « # » devant ce que vous voulez commenter.
Vous pouvez commencer un commentaire au milieu d'une ligne, exemple :
TOTO="10"; # commentaire
Viennent finalement les tests. Avant tout, consultez le man de test (man test) pour apprendre les différents opérateurs de tests.
Il suffit ensuite de mettre l'expression entre crochets « [ ] » :
[ "$TOTO" -eq "10" ]
/!\ ne pas oublier les espaces après le premier crochet et avant le dernier /!\
cette expression est à placer où vous en avez besoin, dans un « if » par exemple :
if [ "$TOTO" -eq "10" ] ; then
fi
Le if se compose donc du mot clé de début « if » suivit de l'expression à tester puis d'un point-virgule « ; » et du mot clé « then » pour préciser le début des commandes à exécuter en cas du succès du test. Enfin, on délimite la fin de notre if avec le mot clé « fi ».
C'est tout pour la partie 1 .
II) L'art de scripter
Dans la partie précédente, nous avons vu l'exemple de 2 scripts assez simples. Il est néanmoins possible de réaliser des scripts plus avancés.
Pour ça, il est important de connaître le plus possible les possibilités offertes par le shell.
Une chose primordiale, et de connaître le fonctionnement des commandes que vous souhaitez utiliser dans votre script, pour ça rien de mieux qu'un petit coup de « man [commande] ».
1)Les variables particulières
Nous avons commencé à voir les variables particulières avec le deuxième script. Nous allons maintenant approfondir cet aspect.
$# correspond donc au nombre de paramètres passés au script (ou à la fonction)
$* contient la liste de tous les paramètres passés au script (ou à la fonction)
$1 contient la valeur du premier paramètre
.
.
.
$9 contient la valeur du neuvième paramètre
Je vous avez dit que pour le dixième (et plus) il y avait une petite subtilité, la voici :
${n} contient la valeur du n-ième paramètre
$? contient le code de retour de la dernière commande exécutée
Voilà pour les principaux.
Il existe également $$ qui contient le pid du processus courant, et $! qui contient le pid du dernier processus lancé en background (avec le &).
2)Les variables
Nous avons vu comment affecter des variables « en dur », ainsi que les conventions de nommage des variables. Il faut savoir que vous pouvez très bien placer le résultat d'une commande dans une variable.
MON_HOME=$(ls $HOME);
/!\ Attention: il n'y a jamais d'espace « » lors d'une affectation de valeur /!\
Désormais, un
cat << EOT
$MON_HOME
EOT
sera équivalent à un
ls $HOME
Dans cet exemple, j'ai également utilisé une variable système, il en existe plusieurs telle que $HOME, $USER, $PWD, etc. (une liste plus complète en bas de cette page : http://doc.ubuntu-fr.org/variables_d_environnement ).
Il est également possible d'utiliser des tableaux.
tab[0]=1;
tab[1]=2;
tab[2]=3;
Pour afficher une valeur du tableau, ${tab[n]} (n étant le rang que l'on souhaite afficher).
${tab[*]} affiche tout le tableau, dans notre cas :
1 2 3
${#tab[*]} affiche lui la taille du tableau, ici 3.
Pour afficher la taille de la chaîne de caractères contenue dans une case du tableau, ${#tab[n]} (n étant l'indice de la case choisie).
Cette dernière écriture, permet également de connaître la taille de n'importe quelle variable, exemple :
MA_CHAINE="toto";
echo ${#MA_CHAINE}; # affiche 4
« $ » étant un caractère spécial, si vous souhaiter l'utiliser comme un caractère standard, il vous suffit d'utiliser un caractère inhibiteur : le back-slash « \ »
Exemple :
echo "Cette guitare coûte \$500"; # affiche « Cette guitare coûte $500 »
3) Les commentaires
Pour les commentaires, rien à ajouter.
Rappel de l'exemple:
DATE=$(date); # j'explique ce que je fais
4) Les fonctions
En shell, la définition de fonctions se fait de la sorte :
nom_de_ma_fonction() {
commande 1;
commande 2;
.
.
.
return 0;
}
Comme pour notre script, notre fonction renvoie un code de retour, mais cette fois-ci avec le mot clé « return ». Un « exit » fonctionnerait mais ce dernier quitte le script.
Il est possible de passer des paramètres à notre fonction, qui seront nommés avec les mêmes convention que celles que nous avons vues plus haut. Attention donc à ne pas les confondre avec les paramètres de notre script.
L'astuce que j'utilise est d'appeler ma fonction avec le paramètre $* si j'ai besoin d'utiliser les paramètres de mon script.
Exemples d'utilisation :
ma_fonction $*;
ma_fonction $2;
ma_fonction toto titi tata;
ma_fonction;
(?) Si vous désirez utiliser ET les paramètres de votre script, ET des paramètres spécifiques à votre fonction, affectez les paramètres de votre script à des variables qui seront accessibles depuis votre fonction.
5) Les structures courantes
Autrement dit, les boucles et les if.
if [ mon test ]
then
echo "success";
else
echo "failed";
fi
while true
do
# boucle infinie
done
Il existe également des boucles for, mais je ne les maîtrise pas :-/ .
Autre structure très utile, le « case »
case $1 in
"-h"|"--help" )
# on affiche l'aide
;;
"-v"|"--version" )
# on affiche la version
;;
* )
# le paramètre n'est pas reconnu
;;
esac
Pour les tests, c'est expliqué plus haut.
Ce qu'il faut savoir, c'est que le if et le while fonctionnent avec les code de retour, il ne vous est donc pas indispensable d'utiliser un test, vous pouvez exécuter une commande, et selon qu'elle réussis ou non, vous effectuez votre traitement.
Exemple :
if cd ~/toto ; then
echo "on est dans le répertoire toto";
else
echo "le répertoire toto n'existe pas";
fi
Cet exemple n'est pas forcement des plus pertinent parce que la commande test permet d'effectuer cette vérification, mais c'était juste pour illustrer.
Enfin, une dernière chose qui peut vous être utile dans les boucles, c'est l'incrémentation ;-)
Ceci est réalisable à l'aide de la commande let (man let) simplifiée par (( )) :
(( i +=1 ))
/!\ Ici également les espaces sont important puis qu'il s'agit d'une commande /!\
Et voilà, on a terminé avec la partie II)
III) Quelques exemples
Petit exemple d'auto-update de script :
NORMAL=$(tput sgr0);
BLEU=$(tput setaf 4);
VERT=$(tput setaf 2);
ROUGE=$(tput setaf 1);
SCRIPT="script.sh"
SCRIPT_SAVE="script.sh.save"
SCRIPT_NEW="script.sh.new"
HOST="http://url_de_votre_site/"
check_update() {
cp $SCRIPT $SCRIPT_SAVE
if wget $HOST/$SCRIPT -q -O $SCRIPT_NEW ; then
diff $SCRIPT $SCRIPT_NEW >/dev/null
if [ $? -eq 1 ] ; then
mv $SCRIPT_NEW $SCRIPT;
chmod u+x $SCRIPT;
cat << EOT
${VERT}Script updated !${NORMAL}
EOT
echo "./$SCRIPT -nc $1";
./$SCRIPT -nc $1;
exit 0;
else
cat << EOT
${ROUGE}you already have the lastest version of the script${NORMAL}
EOT
rm $SCRIPT_NEW;
fi
else
cat << EOT
$FAILED
EOT
exit 1;
fi
}
check_update $1;
exit 0;
-------------------------
Un script de génération d'archives :
NORMAL=$(tput sgr0);
BLEU=$(tput setaf 4);
VERT=$(tput setaf 2);
ROUGE=$(tput setaf 1);
ARCHIVE_NAME="cid.tar.gz";
SAVE=".save";
DEFAULT_FOLDER="archives";
LISTE_FILES="fichier1 fichier2 fichier3 Mon\ fichier";
# liste des fichiers à mettre dans l'archive
make_archive() {
tar cvzf $ARCHIVE_NAME $LISTE_FILES;
if cd $DEFAULT_FOLDER ; then
cp $ARCHIVE_NAME ${ARCHIVE_NAME}$SAVE;
cat << EOT
${BLEU}Backup done${NORMAL}
EOT
mv ../$ARCHIVE_NAME .;
cat << EOT
${VERT}Archive created into ${DEFAULT_FOLDER} folder${NORMAL}
EOT
else
mkdir $DEFAULT_FOLDER;
cd $DEFAULT_FOLDER;
cat << EOT
${BLEU}Folder ${DEFAULT_FOLDER} created${NORMAL}
EOT
mv ../$ARCHIVE_NAME .;
cat << EOT
${VERT}Archive created into ${DEFAULT_FOLDER} folder${NORMAL}
EOT
fi
cd ..;
}
make_archive;
exit 0;
Et voilà, ce tutoriel est terminé
N'hésitez pas à poser vos éventuelles questions, laisser vos remarques, etc...
Si vous souhaitez contribué à ce tutoriel qui n'est certainement pas complet, n'hésitez pas non plus à proposer vos améliorations.
En espérant que ça vous soit utile ;-)
Voici le topic sur lequel je vous propose de poster vos demandes de scripts, et vos propositions de scripts : https://www.jeuxvideo.com/forums/1-38-7670312-1-0-1-0-topick-a-script.htm