Vous n'êtes pas identifié(e).
L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT →
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente Prochaine révision Les deux révisions suivantes | ||
doc:programmation:shells:script-bash-enchainement-de-commandes-et-etat-de-sortie [05/06/2014 07:30] Hypathie [Redirections dans les scripts] |
doc:programmation:shells:script-bash-enchainement-de-commandes-et-etat-de-sortie [20/06/2014 11:48] Hypathie [Enchaînements de commandes dans les scripts] |
||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | ====== script bash : enchaînement de commandes; redirection ====== | + | ====== script bash : enchaînement de commandes et redirection ====== |
- | * Objet : du tuto FIXME | + | * Niveau requis : {{tag>débutant}} |
- | * Niveau requis : FIXME {{tag>débutant avisé}} | + | |
- | * Commentaires : //Contexte d'utilisation du sujet du tuto. // FIXME | + | |
* Débutant, à savoir : [[:doc:systeme:commandes:le_debianiste_qui_papillonne|Utiliser GNU/Linux en ligne de commande, tout commence là !.]] :-) | * Débutant, à savoir : [[:doc:systeme:commandes:le_debianiste_qui_papillonne|Utiliser GNU/Linux en ligne de commande, tout commence là !.]] :-) | ||
- | * Suivi : {{tag>en-chantier à-tester à-placer}} - FIXME Pour choisir, voir les autres Tags possibles dans [[:atelier:#tags|l'Atelier]]. | + | * Suivi : {{tag>à-placer}} |
- | * Création par **Hypathie** 03/06/2014 | + | * Création par **Hypathie** 18/03/2014 |
- | * Testé par <...> le <...> FIXME | + | * Testé par <Hypathie> le <Juin 2014> |
- | * Commentaires sur le forum : [[url | Lien vers le forum concernant ce tuto]] ((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) FIXME | + | * Commentaires sur le forum : [[https://debian-facile.org/viewtopic.php?pid=92203#p92203 | Lien vers le forum concernant ce tuto]] ((N'hésitez pas à y faire part de vos remarques, succès, améliorations ou échecs !)) |
- | **Nota : wiki n°4** | + | **Nota : wiki n°4**\\ |
+ | **Les autres numéros :** | ||
+ | * wiki n°1 : [[atelier:chantier:debuter-avec-les-scripts-shell-bash]] | ||
+ | * wiki n°2 : [[atelier:chantier:script-bash-variables-arguments-parametres|script-bash-variables-arguments-parametres]] | ||
+ | * wiki n°3 : [[atelier:chantier:script-bash-detail-sur-les-parametres-et-les-boucles|modification de variable et de paramètre]] | ||
+ | |||
+ | * wiki n°5 : [[atelier:chantier:script-bash-etat-de-sorie-et-les-tests|script-bash-etat-de-sorie-et-les-tests]] | ||
+ | * wiki n°6 : [[atelier:chantier:script-bash-les-tableaux|script-bash-les-tableaux]] | ||
+ | * wiki n°7 : [[atelier:chantier:script-bash-les-fonctions|script-bash-les-fonctions]] | ||
Contributeurs, les FIXME sont là pour vous aider, supprimez-les une fois le problème corrigé ou le champ rempli ! | Contributeurs, les FIXME sont là pour vous aider, supprimez-les une fois le problème corrigé ou le champ rempli ! | ||
- | ===== enchaînements de commandes dans les scripts===== | + | =====Enchaînements de commandes dans les scripts===== |
Parmi les opérateurs d'enchaînement de commandes (voir [[atelier:chantier:bash-les-differents-caracteres-speciaux#les-operateurs-de-controle|les opérateurs de contrôle]])\\ | Parmi les opérateurs d'enchaînement de commandes (voir [[atelier:chantier:bash-les-differents-caracteres-speciaux#les-operateurs-de-controle|les opérateurs de contrôle]])\\ | ||
- | * considérons : | + | * considérons maintenant : |
<code> | <code> | ||
& && ; ( ) { } | & && ; ( ) { } | ||
</code> | </code> | ||
- | Pour les opérateurs de contrôle et l'enchaînement conditionné ( && ; || ) voir : [[atelier:chantier:script-bash-etat-de-sorie-et-les-tests?&#etat-de-sortie-et-code-de-retour|état de sortie et code de retour]] | + | //(Pour ce qui concerne les opérateurs de contrôle du point de vue de **l'enchaînement conditionné** (avec && ; || ) voir : [[atelier:chantier:script-bash-etat-de-sorie-et-les-tests?&#etat-de-sortie-et-code-de-retour|état de sortie et code de retour]]).// |
- | ====parallélisme et successivité ==== | + | ====parallélisme et succession & , && et ;==== |
- | ===1) les opérateurs & , && et ;=== | ||
Reprenons le script "scriptx", et changeons les ";" d'abord par "&", puis par "&&" | Reprenons le script "scriptx", et changeons les ";" d'abord par "&", puis par "&&" | ||
<code bash> | <code bash> | ||
Ligne 49: | Ligne 54: | ||
</note> | </note> | ||
- | ====Regroupement de commandes==== | + | ====Regroupement de commandes, parenthèses ou accolades ?==== |
le shell bash fournit deux mécanismes pour regrouper les commandes; l'insertion de la suite de commandes entre accolades et l'insertion de cette suite de commandes entre une paire de parenthèses. | le shell bash fournit deux mécanismes pour regrouper les commandes; l'insertion de la suite de commandes entre accolades et l'insertion de cette suite de commandes entre une paire de parenthèses. | ||
Ligne 88: | Ligne 93: | ||
Il n'y a donc pas besoin d'espace entre la parenthèse ouvrante et la première commande.\\ | Il n'y a donc pas besoin d'espace entre la parenthèse ouvrante et la première commande.\\ | ||
Insérée dans une parenthèse, la suite de commandes est exécutée dans un sous-shell.\\ | Insérée dans une parenthèse, la suite de commandes est exécutée dans un sous-shell.\\ | ||
- | Les variables comprises dans ces parenthèses, à l'intérieur du sous-shell, ne sont pas visibles par le reste du script. Le **processus parent**, le script, ne peut pas lire les variables créées dans le processus fils, le sous-shell. | ||
<code bash> | <code bash> | ||
Ligne 94: | Ligne 98: | ||
nom=nenette | nom=nenette | ||
(prenom=hypathie ; echo $prenom ) | (prenom=hypathie ; echo $prenom ) | ||
- | echo $nom $prenom | + | echo $nom |
</code> | </code> | ||
Retour : | Retour : | ||
<code> | <code> | ||
+ | hypathie | ||
nenette | nenette | ||
</code> | </code> | ||
Voir : [[http://abs.traduc.org/abs-fr/ch21.html|Guide avancé d'écriture des scripts Bash: 21. Sous-shells]] | Voir : [[http://abs.traduc.org/abs-fr/ch21.html|Guide avancé d'écriture des scripts Bash: 21. Sous-shells]] | ||
- | =====Redirections dans les scripts===== | + | <note tip> |
- | Prérequis : [[doc:programmation:shell:shell#rediriger-l-affichage]] et le lien qu'on y trouve [[doc:programmation:shell:chevrons]] | + | On ne confondra plus ! |
- | Voir : [[atelier:chantier:bash-les-differents-caracteres-speciaux#les-operateurs-de-redirection|les opérateurs de redirection]] | + | |
- | ====Rappels :==== | + | |
- | + | ||
- | Les redirections permettent de travailler non pas en se servant du code de retour (qui indique la réussite ou l'échec de l'exécution d'une commande) mais sur les flux.\\ | + | |
- | Un processus unix possède (par défaut) trois voies d'interaction entre le système et l'utilisateur. Une entrée et deux sorties. Chacun de ces "lieux" sont identifiés par un descripteur de fichier. | + | |
- | -une entrée standard (par défaut le clavier stdin), de descripteur 0 (nom de l'entrée du processus, ne pas confondre avec le code de retour !); | + | |
- | -une sortie standard (par défaut l'écran stdout), de descripteur 1 ; | + | |
- | -une sortie standard pour les message d'erreur (stderr) de descripteur 2. | + | |
- | + | ||
- | Pour chaque programme lancé, un flux est créé. Ce flux est une sorte de canal par lequel transite les données entre les espaces, entrée et sortie.\\ | + | |
- | On peut imaginer un terminal, comme la réunion virtuelle d'un clavier et d'un écran. | + | |
- | **Merci à captnfab pour cette comparaison sur IRC** :-D | + | |
<code bash> | <code bash> | ||
- | <&- <&- # Permettent la fermeture de l'entrée standard et de la sortie standard. | + | #!/bin/bash |
- | >| # Force une redirection vers un fichier.txt pour pouvoir écraser | + | { var1=yep ;} |
- | le fichier quand il existe et que l'option noclobber (-c) est activée. | + | echo $var1 |
+ | var3=coucou | ||
+ | { var4=yep ; $var4 ;} | ||
+ | echo $var3 | ||
</code> | </code> | ||
- | ====1) opérateurs de sortie : ==== | + | retour : |
- | <code bash> | + | <code> |
- | > : crée un fichier ou le réactualise ; redirige le canal choisi vers un fichier et force sa création, | + | yep |
- | si le fichier existe son contenu est recrée et numéro d'inode du fichier d'origine est conservé. | + | essai.sh: ligne5: yep : commande introuvable |
+ | coucou | ||
</code> | </code> | ||
+ | |||
+ | Mais : | ||
<code bash> | <code bash> | ||
- | ls -l >chemin-fichier.txt | + | #!/bin/bash |
+ | var1=coucou | ||
+ | (var2=yep ) | ||
+ | echo $var1 $var2 | ||
+ | ( var3="au revoir" ; echo $var3 ) | ||
</code> | </code> | ||
- | est un équivalent de : | + | retour : |
- | <code bash> | + | <code> |
- | ls -l 1> chemin-fichier.txt | + | coucou |
+ | au revoir | ||
</code> | </code> | ||
- | ===Dans un script :=== | + | </note> |
- | <code bash> | + | |
- | #!/bin/bash | + | |
- | # mise en place : | + | |
- | { mkdir ~/ABCD ; cd ABCD ; touch a b c d ; cd ~ ; pwd ;} | + | |
- | # création de fichier avec " > " : | + | ====Notion de sous-shell ==== |
- | cd ~/ABCD && > fichier1 && pwd ; cd ~ && pwd && > /home/hypathie/ABCD/fichier2 && pwd && cd ~ && pwd | + | Les variables comprises dans ces parenthèses, à l'intérieur du sous-shell, ne sont pas visibles par le reste du script. Le **processus parent** ne peut pas lire les variables créées dans le processus fils, le sous-shell. |
- | # espace facultatif avant et après " > " | + | |
- | # redirection de la sortie de commande vers un fichier : | + | Dans le script ci-dessus on voit que le terminal "reçoit le retour du shell père et celui du shell fils ( "echo $prenom" ). |
- | ls>/home/hypathie/ABCD/recup-ls # espace facultatif avant et après " > " | + | |
+ | ===Le processus père ne peut pas récupérer les variables d'un processus fils=== | ||
+ | |||
+ | <code bash> | ||
+ | #!/bin/bash | ||
+ | nom=nenette | ||
+ | ( prenom=hypathie ) | ||
+ | echo $nom $prenom | ||
</code> | </code> | ||
Retour : | Retour : | ||
+ | |||
+ | nenette | ||
+ | | ||
+ | Créer un sous-shell permet ainsi de protéger de ce qui se passe dans le processus fils.\\ | ||
+ | Créer un processus fil permet aussi au processus père de continuer son programme "pendant" l'exécution du processus fils : ça évite de ralentir l'ensemble du programme. | ||
+ | |||
+ | <note tip> | ||
+ | En graphique, un sous-shell pour récupérer la main sur le terminal, c'est bien pratique 8-)\\ | ||
+ | Comparez : | ||
<code bash> | <code bash> | ||
- | /home/hypathie # après cd ~ on est retourné dans le répertoire de l'utilisateur | + | virtualbox |
- | /home/hypathie/ABCD # après création du fichier1 on est encore dans "ABCD" | + | |
- | /home/hypathie # après cd ~ on est retourné dans le répertoire utilisateur | + | |
- | /home/hypathie # on a créé fichier2 dans "ABCD" depuis le répertoire utilisateur | + | |
- | /home/hypathie | + | |
</code> | </code> | ||
- | <note important> | + | avec : |
- | Attention: | + | <code bash> |
- | Créer un fichier avec > est un bashisme. La méthode universelle est d'utiliser "touch". | + | virtualbox & |
- | Amateurs de magie blanche et noire voir ce fil : [[http://debian-facile.org/viewtopic.php?pid=86634#p86634]] | + | [1] 4245 |
+ | </code> | ||
+ | //Ici "[1]" est le jobID et "4245" est PID, l'identifiant du processus.//\\ | ||
+ | //(Pour aller plus loin voir la notion de processus et les commandes : ps ; top ; nice et renice.)// | ||
+ | |||
+ | Dans les deux cas, si l'on ferme le terminal, on ferme aussi "virtualbox", processus fils du shell ; mais avec & le processus fils est en arrière plan et l'on peut donc utiliser le shell. | ||
</note> | </note> | ||
- | *redirection de commande vers un fichier, si le fichier existe, les données sont ajoutées à la suite du fichier. | + | ===Lancer deux sous-shell en parallèle === |
+ | Il est possible de lancer deux processus en parallèle. | ||
+ | Comparez le retour des lignes n°2 et n°3 avec celles des lignes n°5 et n°6 du code ci-dessous. | ||
<code bash> | <code bash> | ||
- | >> | + | #!/bin/bash |
+ | ( echo "bonjour" ) & ( echo "au revoir" ) | ||
+ | ( cd /etc/apt ; ls ) & ( cd /etc/calendar ; ls ) | ||
+ | echo " " | ||
+ | cd /etc/apt ; ls | ||
+ | cd /etc/calendar ; ls | ||
</code> | </code> | ||
- | *La sortie standard d'erreur peut être dirigée vers un fichier en le créant ou en l'écrasant : | + | |
+ | ====Le shell restreint ==== | ||
+ | ===Passer en mode restreint === | ||
+ | |||
+ | set --restricted | ||
+ | |||
+ | ( ou set -r) | ||
+ | |||
+ | ===à quoi ça sert dans les scripts ?=== | ||
+ | On passe en mode restreint pour diminuer les risques.\\ | ||
+ | En mode restreint, certaines commandes sont désactivées : | ||
+ | * cd | ||
+ | * exec (commande qui permet des substitution de processus | ||
+ | * empêche de sortir du mode restreint depuis le script qui la mis en place | ||
+ | * empêche les redirections de sortie (écrire dans des fichiers) | ||
+ | * empêche l'utilisation de commandes contenant des / (pour éviter des modification à la racine) | ||
+ | * empêche de modifier les valeurs des variables d'environnement | ||
+ | * $PATH : en le modifiant on peut changer l'utilisation de certaines commandes. | ||
+ | * $SHELL : en le modifiant on peut utiliser un autre interpréteur, en cours de programme. | ||
+ | * $BASH_ENV et $ENV : les modifications de l'environnement ne se font pas sans connaissances. | ||
+ | * $SHELLOPTS : où on peut changer les options d'environnement du shell | ||
+ | * et les droits sont limités. | ||
+ | =====Redirections et le pipe ===== | ||
+ | * Liste des opératieurs : [[atelier:chantier:bash-les-differents-caracteres-speciaux#les-operateurs-de-redirection|un tableau des opérateurs de redirection]] | ||
+ | * Exercices dans le terminal, tout est là : [[doc:programmation:shell:chevrons| les chevrons]] | ||
+ | |||
+ | ==== Redirections : quelques points importants pour les scripts==== | ||
+ | ===Rappels sur les flux === | ||
+ | Les redirections permettent de travailler non pas en se servant du code de retour (qui indique la réussite ou l'échec de l'exécution d'une commande) mais sur les flux.\\ | ||
+ | Un processus unix possède (par défaut) trois voies d'interaction entre le système et l'utilisateur. Une entrée et deux sorties. Chacun de ces "lieux" sont identifiés par un descripteur de fichier. | ||
+ | -une entrée standard (par défaut le clavier stdin), de descripteur 0 (nom de l'entrée du processus, ne pas confondre avec le code de retour !); | ||
+ | -une sortie standard (par défaut l'écran stdout), de descripteur 1 ; | ||
+ | -une sortie standard pour les message d'erreur (stderr) de descripteur 2. | ||
+ | |||
+ | Pour chaque programme lancé, un flux est créé. Ce flux est une sorte de canal par lequel transite les données entre les espaces, entrée et sortie.\\ | ||
+ | On peut imaginer un terminal, comme la réunion virtuelle d'un clavier et d'un écran. | ||
+ | **Merci à captnfab pour cette comparaison sur IRC** :-D | ||
+ | <code bash> | ||
+ | <&- <&- # Permettent la fermeture de l'entrée standard et de la sortie standard. | ||
+ | >| # Force une redirection vers un fichier.txt pour pouvoir écraser | ||
+ | le fichier quand il existe et que l'option noclobber (-c) est activée. | ||
+ | </code> | ||
+ | |||
+ | ===Utilisation de la sortie d'erreur dans les scripts=== | ||
+ | |||
+ | * La sortie standard d'erreur peut être dirigée vers un fichier en le créant ou en l'écrasant : | ||
<code bash> | <code bash> | ||
ls vi 2>err # retour du prompt : le message d'erreur a été inscrit | ls vi 2>err # retour du prompt : le message d'erreur a été inscrit | ||
Ligne 219: | Ligne 287: | ||
c'est-à-dire le fichier "erreur". | c'est-à-dire le fichier "erreur". | ||
</code> | </code> | ||
- | ====2)Opérateurs d'entrée : ==== | ||
- | <code bash> | ||
- | < Place, en entrée d'une commande, un contenu. | ||
- | </code> | ||
- | <code bash> | ||
- | cat < /chemin/du/fichier.txt # est un équivalent de cat /chemin/du/fichier.txt | ||
- | </code> | ||
- | <code bash> | ||
- | << Redirige en entrée une série de données. | ||
- | </code> | ||
- | On nomme cette redirection "label".\\ Redirection utilisée dans un document en ligne dont on se sert que pour certaines commandes, comme ftp ou cat.\\ Voir : [[http://abs.traduc.org/abs-5.0-fr/ch18.html#heredocref]]\\ | ||
- | Ne pas confondre avec la commande e2label, voir : [[doc:systeme:e2label]] | ||
- | ====3) Un petit exercice sur opérateurs ==== | + | ===Utilisation du "text processing" === |
+ | * Tout est là : [[http://wiki.debian-facile.org/atelier:chantier:les-commandes-join-paste-split-et-nl|http://wiki.debian-facile.org/atelier:chantier:les-commandes-join-paste-split-et-nl]] | ||
+ | |||
+ | ====Un petit exercice sur opérateurs d'enchaînement et de redirection==== | ||
+ | ===énoncé=== | ||
Écrire un script qui crée le dossier "ABCD" et 4 fichiers vides (nommés a b c d) ; | Écrire un script qui crée le dossier "ABCD" et 4 fichiers vides (nommés a b c d) ; | ||
qui liste le contenu de "ABCD" et qui inscrit le résultat dans un fichier nommé "ls1" qui sera placé dans "ABCD" ; | qui liste le contenu de "ABCD" et qui inscrit le résultat dans un fichier nommé "ls1" qui sera placé dans "ABCD" ; | ||
Ligne 239: | Ligne 299: | ||
puis une deuxième ligne de texte dans "fichier.txt", en affichant dans le terminal,\\ le nombre de lignes, de mots et d'octets que possède le fichier "fichier.txt" ; | puis une deuxième ligne de texte dans "fichier.txt", en affichant dans le terminal,\\ le nombre de lignes, de mots et d'octets que possède le fichier "fichier.txt" ; | ||
se servir de différentes méthodes tout au long du script pour vérifier\\ au niveau du terminal que chaque commande s'est bien déroulée. | se servir de différentes méthodes tout au long du script pour vérifier\\ au niveau du terminal que chaque commande s'est bien déroulée. | ||
+ | <note important> | ||
+ | Attention: | ||
+ | Créer un fichier avec > est un bashisme. La méthode universelle est d'utiliser "touch". | ||
+ | Amateurs de magie blanche et noire voir ce fil : [[http://debian-facile.org/viewtopic.php?pid=86634#p86634]] | ||
+ | </note> | ||
+ | ===une solution=== | ||
Bonne lecture ;-) | Bonne lecture ;-) | ||
<code bash> | <code bash> | ||
Ligne 265: | Ligne 330: | ||
cat < ~/ABCD/fichier.txt | wc | cat < ~/ABCD/fichier.txt | wc | ||
echo $? ;} | echo $? ;} | ||
- | </code> | ||
- | Retour : | ||
- | <code> | ||
- | 0 | ||
- | 0 | ||
- | 0 | ||
- | /home/hypathie | ||
- | 0 | ||
- | /home/hypathie | ||
- | 0 | ||
- | J'écris un script, | ||
- | 0 | ||
- | avec les opérateurs de redirection. | ||
- | 0 | ||
- | 2 8 57 | ||
- | 0 | ||
</code> | </code> | ||
+ | |||
* **2>>/dev/null** : permet ici de relancer le script autant de fois qu'on veut, sans voir apparaître de message d'erreur : mkdir fichier-existant ne réinitialise pas un fichier de type dossier en le vidant. | * **2>>/dev/null** : permet ici de relancer le script autant de fois qu'on veut, sans voir apparaître de message d'erreur : mkdir fichier-existant ne réinitialise pas un fichier de type dossier en le vidant. | ||
* **$?** : permet ici de vérifier que la commande précédente s'est déroulée avec succès quand "**;**" a été utilisé, inutile de vérifier avec **&&**. | * **$?** : permet ici de vérifier que la commande précédente s'est déroulée avec succès quand "**;**" a été utilisé, inutile de vérifier avec **&&**. | ||
+ | ====Le pipe ==== | ||
+ | |||
+ | Tout est là : [[doc:programmation:shell:pipe|le pipe]] | ||
+ | =====La suite c'est ici===== | ||
+ | [[atelier:chantier:script-bash-etat-de-sorie-et-les-tests|script-bash-etat-de-sorie-et-les-tests]] |