info:bash:pipeline:code_retour

Ceci est une ancienne révision du document !


Gérer les codes retours des commandes en pipelines

les pipelines en bash, rappel: Ils permettent d'enchainer des commandes en passant le résultat (stdout), mais pas le code retour, d'une commande a la suivante.

commande 1 | commande 2 | commande 3 ....

exemple:

ls -AdU1 /existe/pas/* | tail -1
echo $?
0

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 /opt/rep n'existe pas, par exemple, le code retour sera quand même, et toujours, celui de la commande “tail -1”, c'est a dire 0

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. Ne mettez pas cette commande en premier, sinon vous fermer le shell principale.Un pipe ouvre un sous-shell et la commande “exit” permet de quitter ce sous-shell créé par le pipe “|”.

Pour la commande ci-dessous, la variable PIPESTATUS[0] renvoi le code retour de “true”, soit 0

true | exit 10 | exit 20 | exit 30 | exit 40 | exit 50 | exit 60
echo "\${PIPESTATUS[0]}=${PIPESTATUS[0]}"
0

Pour la commande ci-dessous, la variable PIPESTATUS[4] renvoi le code retour de la 5e commande “exit 40”, soit 40

true | exit 10 | exit 20 | exit 30 | exit 40 | exit 50 | exit 60
echo "\${PIPESTATUS[0]}=${PIPESTATUS[4]}"
${PIPESTATUS[0]}=40
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

Pour afficher tous les codes retour des commandes du pipeline:

true | exit 11 | exit 22 | exit 33 | exit 44 | exit 55 | exit 66
echo "${PIPESTATUS[@]}"
0 11 22 33 44 55 66

Cela est souvent un problème notamment dans les scripts ou dans les commandes Ansible.
L'option “pipefail” stop les commandes en pipeline lorsque le code retour est différent de 0 et renvoi ce code d'erreur.

#!/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"


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:

- 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
  • /home/franck/dokuwiki/doc/data/attic/info/bash/pipeline/code_retour.1668250642.txt.gz
  • Dernière modification : 2022/11/12 11:57
  • de franck