info:bash:pipeline:code_retour

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
info:bash:pipeline:code_retour [2022/11/12 11:57] – supprimée - modification externe (Unknown date) 127.0.0.1info:bash:pipeline:code_retour [2022/12/03 10:50] (Version actuelle) franck
Ligne 1: Ligne 1:
 +======Gérer les codes retours des commandes en pipelines======
 +les pipelines en bash, rappel: Ils permettent d’enchaîner des commandes en passant le résultat (stdout), **mais pas le code retour**, d'une commande a la suivante.
 +<code bash>
 +commande 1 | commande 2 | commande 3 ....
 +</code>
 +exemple:
 +<code bash>
 +ls -AdU1 /existe/pas/* | tail -1
 +echo $?
 +0
 +</code>
 +Les lignes de commandes avec des pipes renvoi le **code retour de la dernière commande**. dans l'exemple ci-dessus, si le répertoire /existe/pas/ n'existe pas, le code retour sera quand même, et toujours,  celui de la commande **"tail -1"**, c'est a dire **0**\\
 +Pour gérer les codes retours des commandes a l’intérieur des pipelines, il existe des solutions, voir ci-dessous.
  
 +=====Le tableau de variables PIPESTATUS[ ]=====
 +Pour une ligne de commande avec des pipes, le tableau de variable PIPESTATUS[] va afficher le code retour des commandes du pipe, en commençant a 0 pour la première commande.\\
 +PIPESTATUS[] se comporte comme un tableau bash.\\
 +\\
 +A noter pour les exemples: "exit" permet de quitter un shell ou un sous-shell avec un code retour. Hors la première commande d'un pipe s’exécute dans le shell courant. Si vous mettez exit, le shell courant est fermé et la suite du script n'est pas exécuté. Un pipe ouvre un sous-shell et la commande "exit" permet de quitter ce sous-shell créé par le pipe "|". Vous ne quittez donc pas le shell d'origine.\\
 +\\
 +Pour la commande ci-dessous, la variable PIPESTATUS[0] renvoi le code retour de "true", soit 0
 +<code bash>
 +true | exit 10 | exit 20 | exit 30 | exit 40 | exit 50 | exit 60
 +echo "\${PIPESTATUS[0]}=${PIPESTATUS[0]}"
 +0
 +</code>
 +Pour la commande ci-dessous, la variable PIPESTATUS[4] renvoi le code retour de la 5e commande "exit 40", soit 40
 +<code bash>
 +true | exit 10 | exit 20 | exit 30 | exit 40 | exit 50 | exit 60
 +echo "\${PIPESTATUS[4]}=${PIPESTATUS[4]}"
 +${PIPESTATUS[4]}=40
 +</code>
 +<code bash>
 +true | exit 10 | exit 20 | exit 30 | exit 40 | exit 50 | exit 60
 +echo -e "\${PIPESTATUS[0]}=${PIPESTATUS[0]}\n\${PIPESTATUS[1]}=${PIPESTATUS[1]}\n\${PIPESTATUS[2]}=${PIPESTATUS[2]}\n\
 +\${PIPESTATUS[3]}=${PIPESTATUS[3]}\n\${PIPESTATUS[4]}=${PIPESTATUS[4]}\n\${PIPESTATUS[5]}=${PIPESTATUS[5]}\n\
 +\${PIPESTATUS[6]}=${PIPESTATUS[6]}"
 +${PIPESTATUS[0]}=0
 +${PIPESTATUS[1]}=10
 +${PIPESTATUS[2]}=20
 +${PIPESTATUS[3]}=30
 +${PIPESTATUS[4]}=40
 +${PIPESTATUS[5]}=50
 +${PIPESTATUS[6]}=60
 +
 +</code>
 +Pour afficher tous les codes retour des commandes du pipeline:
 +<code bash>
 +true | exit 11 | exit 22 | exit 33 | exit 44 | exit 55 | exit 66
 +echo "${PIPESTATUS[@]}"
 +0 11 22 33 44 55 66
 +</code>
 +=====option pipefail=====
 +les codes retours différents de 0 d'une commande a l’intérieur d'un pipeline est souvent un problème notamment dans les scripts ou dans les commandes Ansible.\\
 +L'option "pipefail" stop/arrête l’exécution du pipeline sur la commande en erreur, c'est a dire, lorsque le code retour d'une des commandes est différent de 0.\\
 +<code bash>
 +#!/usr/bin/env bash
 +set -o pipefail
 +....
 +grep "chaine" /non/existent/fichier | tail -1
 +if  [[ $? == 0 ]] 
 +do 
 +    printf "l execution a réussi\n"
 +else
 +    printf "échec de la recherche\n"
 +</code>
 +
 +====pipefail dans une commande Ansible====
 +Dans une commande Ansible vous pouvez utiliser l'option en début de ligne, et elle sera valable pour toute la ligne.\\
 +Vous pouvez ainsi récupérer le code retour d'erreur du pipeline avec un arrêt de l’enchaînement des commandes par pipe sur la commande en erreur. par exemple:
 +<code yaml>
 +- name: Recuperer le nom de répertoire numérique de la version la plus élevé dans /opt/rep/nn/
 +  shell: set -o pipefail && cd /opt/{{ rep }}/ && ls -AdU1 ?? | tail -1
 +  register: rep_version
 +</code>