2017-08-01 1 views
3

Ceci est une question complémentaire à mon last question lors d'un débordement de pile. Je vais couper le script pour les parties essentielles, mais si le s.o. pense, il pourrait être utile de savoir ce que le script fait, vous pouvez regarder dans l'autre question.Le script bash se ferme de façon inattendue après le retour de la fonction

#!/usr/bin/env bash 
set -eu -o pipefail 

declare -a framelist 


#Print all results 

function output_values() { 
    echo "Results!"; 
} 

#parsing information from stdin 

function parser() { 

    while read tc; 
    do 

     if [ -z "$tc" ]; then 
     continue 
     fi 

     #Evaluation and saving result to array 

     echo $result_value; 

     framelist+=($result_value); 

     if ((<<some abort condition>>)); then 
     exec 0>&- 
     echo "Last result: $result_value"; 
     return 0 
     fi 

    done 
} 

some_command_writing_to_stdout | parser $2; 
output_values; 

Le script exécute la commande et la sortie des tuyaux à ma fonction locale qui retourne enfin un résultat à la ligne echo "Last result: $result_value"; comme il est prévu de le faire. Après cela, il doit terminer la commande qui fournit les données qui sont analysées dans cette fonction - cela fonctionne aussi.

En atteignant return 0, je pense, la ligne suivante du script (juste en dessous de la commande) output_values; devrait être exécutée, mais ce n'est pas le cas.

Même si j'appelle la fonction output_values ​​directement avant la ligne d'écho, qui imprime le résultat dans la fonction d'analyseur, elle n'est pas exécutée.

Cela devient encore plus bizarre, car je peux commenter exec 0>&- et tous se comportent tout de même. Même la commande qui devrait être terminée par cette ligne, se termine, dès que la fonction d'analyseur est quittée.

Que dois-je changer pour pouvoir travailler avec les résultats de ma fonction d'analyseur, après son retour? Cela ne peut pas être un comportement intentionnel.

Cordialement

Manuel

+0

après un exemple de code qui est simple, travailler et produire l'échec exact – Anubis

+0

Avez-vous essayé 'set -x'? –

+0

'set -x' montre juste la sortie après' return 0' et rien n'est exécuté par la suite. –

Répondre

4

Jetons un coup d'œil à man bash, section pipefail:

pipefail

Si elle est définie, la valeur de retour d'un pipeline est le valeur de la dernière commande (la plus à droite) pour quitter avec un non état zéro ou zéro si toutes les commandes du pipeline se terminent correctement. Cette option est désactivée par défaut.

Combiné avec set -e, qui sortira chaque fois qu'une commande (pipeline) sort avec le statut de sortie non nul, la seule conclusion logique est: votre some_command_writing_to_stdout doit être la sortie d'un état de sortie non nul (parce que évidemment, il existe parser avec 0).

Cela expliquerait pourquoi la commande suivante dans le pipeline (parser) est exécutée, et pourquoi votre script se termine après cela.

Il est assez facile de vérifier cela. Il suffit de remplacer l'avant-dernière déclaration avec:

(some_command_writing_to_stdout || true) | parser $2 
+0

Vous avez absolument raison. J'ai commenté l'option pipefail et ça marche. Je m'attendais à obtenir des informations sur le code de sortie! = 0 étant la cause de la sortie immédiate du script lors de l'utilisation de 'set -x', cependant. –

+0

N'obtenez-vous pas le code de sortie de 'some_command_writing_to_stdout'? – randomir

+0

Le script génère les valeurs qu'il obtient en analysant les données de sortie stdoutées et la ligne "last result". L'utilisation de 'set -x' ne fournit pas plus d'informations que la dernière ligne en cours d'exécution est' return 0'. –