====== Fonctionnalités avancées du Shell ======
* Objet : Fonctionnalités avancées du Shell
* Niveau requis : {{tag>avisé}}
* Commentaires : //Faire des choses compliquées avec votre shell.//
* À savoir : [[:doc:programmation:shell:]]
* Suivi :
* Création par [[user>captnfab]] le 30/09/2013
* Testé par [[user>smolski]] le 01/10/2013
* Commentaires sur le forum : [[http://debian-facile.org/viewtopic.php?pid=68350 | ici]] ((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !))
===== Boucles et instructions conditionnelles =====
Une instruction conditionnel (souvent appelé //bloc if-then-else// ou //bloc si-alors-sinon// se construit via une condition, et exécute une série de commandes ou une autre suivant le résultat de la condition.
==== Les conditions ====
En shell, les conditions s'expriment de la manière suivante :
=== Sur les fichiers et les dossiers ===
| Condition | Description | Exemple |
| ''[ -e fichier ]'' | //vrai// si ''fichier'' existe | [ -e /etc/network/interfaces ]
|
| ''[ -d dossier ]'' | //vrai// si ''dossier'' est un répertoire | [ -d /etc/network ]
|
| ''[ -f fichier ]'' | //vrai// si ''fichier'' est un fichier régulier | [ -f /etc/resolv.conf ]
|
| ''[ -L fichier ]'' | //vrai// si ''fichier'' est un lien symbolique | [ -L /usr/bin/x-terminal-emulator ]
|
| ''[ -r fichier ]'' | //vrai// si fichier est lisible (r) | [ -r /bin/bash ]
|
| ''[ -w fichier ]'' | //vrai// si fichier est modifiable (w) | [ -w /tmp ]
|
| ''[ -x fichier ]'' | //vrai// si fichier est exécutable (x) | [ -x /sbin/ifconfig ]
|
| ''[ f1 -nt f2 ]'' | //vrai// si f1 plus récent que f2 | [ /tmp/bla -nt /tmp/bli ]
|
| ''[ f1 -ot f2 ]'' | //vrai// si f1 plus ancien que f2 | [ /tmp/bla -ot /tmp/bli ]
|
=== Sur les chaînes de caractères ===
| Condition | Description | Exemple |
| ''[ -z chaîne ]'' | //vrai// si ''chaîne'' est vide | [ -z "$VAR" ]
|
| ''[ -n chaîne ]'' | //vrai// si ''chaîne'' est non-vide | [ -n "$VAR" ]
|
| ''[ c1 = c2 ]'' | //vrai// si les chaînes ''c1'' et ''c2'' sont identiques | [ "$ARG1" = "$VAR" ]
|
| ''[ c1 != c2 ]'' | //vrai// si les chaînes ''c1'' et ''c2'' sont différentes | [ "plouf" != "$VAR" ]
|
=== Sur les nombres entiers ===
| Condition | Description | Exemple |
| ''[ n1 -eq n2 ]'' | //vrai// si les nombres ''n1'' et ''n2'' sont égaux | [ "$num" -eq 42 ]
|
| ''[ n1 -ne n2 ]'' | //vrai// si les nombres ''n1'' et ''n2'' sont inégaux | [ "$num" -ne 42 ]
|
| ''[ n1 -lt n2 ]'' | //vrai// si les ''n1'' est strictement inférieur à ''n2'' | [ "$num" -lt 42 ]
|
| ''[ n1 -le n2 ]'' | //vrai// si les ''n1'' est inférieur ou égal à ''n2'' | [ "$num" -le 42 ]
|
| ''[ n1 -gt n2 ]'' | //vrai// si les ''n1'' est strictement supérieur à ''n2'' | [ "$num" -gt 42 ]
|
| ''[ n1 -ge n2 ]'' | //vrai// si les ''n1'' est supérieur ou égal à ''n2'' | [ "$num" -ge 42 ]
|
==== Instruction conditionnelle ''if'' ====
Pour exécuter ''commande1'' si ''condition'' est vraie, et ''commande2'' sinon, la syntaxe est la suivante :
if condition;
then
commande1;
else
commande2;
fi
''condition'' est en fait un programme. On considère que ''condition'' est //vrai// s'il se termine bien et retourne un code de retour ''0'', et //faux// sinon.
Par exemple, ''/bin/true'' est un programme fournissant une condition toujours vrai :
if /bin/true;
then
echo 'Je suis dans le vrai'
else
echo 'Je suis dans le faux'
fi
Le copié/collé puis la validation de cette instruction vous donnera :
Je suis dans le vrai.
//Ce qui n'est donc pas un mensonge !// ;-)
D'autres exemples utilisant les conditions prédéfinies :
Cette commande vérifie s'il existe un fichier ''/bin/echo'' qui soit exécutable. Si c'est le cas, il l'utilise pour afficher « Bonjour le monde. », sinon il utilise la commande ''echo'' intégrée au shell.
if [ -e /bin/echo ] && [ -x /bin/echo ];
then
/bin/echo 'Bonjour le monde.'
else
echo 'Bonjour le monde.'
fi
if [ "$USER" = "smolski" ];
then
echo 'Salut chef !'
else
echo "Bonjour $USER."
fi
==== Boucle tant que ''while'' ====
while condition;
do
commande;
done
Les conditions sont les mêmes que pour la commande ''if''.
==== Boucle pour tout ''for'' ====
for i in "les fleurs" "le lapin" "le chou" "la salade" "le staff DF";
do
echo "J'aime $i."
done
("in" est un mot-clé que l'on peut traduire par "au sein de")
==== Sélecteur ''case'' ====
read x ; case "$x" in
bonjour)
echo "Bonjour $USER"
;;
aurevoir)
echo "Au revoir $USER"
;;
*)
echo "Que voulez-vous dire par '$x' $USER ?"
esac
===== Les fonctions =====
La syntaxe à utiliser dans le corps d'une fonction pour en récupérer les arguments est similaire à celle d'un fichier de script.\\
Pour une explication sur les différentes syntaxes voir : [[doc:programmation:shells:bash-les-differents-caracteres-speciaux#les-fonctions]]\\
Rappel :
*Pour le reste, le corps d'une fonction se définit de manière assez simple. Notons que les arguments ne sont pas précisés entre parenthèses.
*L'appel de la fonction se fait ensuite comme l'appel d'un programme (cf. dernière ligne.)
function ma_fonction()
{
echo "Commande initiale : $0 $@"
N=0
while [ -n "$1" ];
do
N=$(($N+1))
echo "Argument $N : $1";
shift;
done
}
ma_fonction test bla coucou plouf
===== Quelques liens =====
Des scripts en cascade commentés en anglais.
La page documentation :
* http://mywiki.wooledge.org/BashGuide
La page scripts :
* http://mywiki.wooledge.org/BashFAQ/
//Merci //**cthuluh** ! :-)
===== Références =====
[[http://abs.traduc.org/abs-fr/|Guide avancé d'écriture des scripts Bash]]