Forum Programmation.shell exit qui exit pas

Posté par  .
Étiquettes : aucune
0
26
mai
2009
Bonsoir @tous,

voilà mon problème :

$ cat plop.sh
#!/bin/sh

while true
do
echo plop
exit 1
done | cat -

echo fin
$ ./plop.sh
plop
fin


J'ai essayé avec un while => pareil et avec un tee comme commande pipé => pareil.

Si quelqu'un pouvait me trouver une explication à pourquoi le exit sort pas du script, ça m'interesse vraiment.

Merci d'avance aux bonnes ames,
  • # http://www.chezmoicamarche.org/

    Posté par  . Évalué à 8.

    C'est bien le comportement normal, car "piper" tout le bloc while est équivalent à le mettre entre parenthèses, c'est à dire l'exécuter dans un sous-shell.
    L'exit sort donc bien du script en cours d'exécution, c'est-à-dire juste le while.

    De la même façon, tu ne saurais pas, à l'intérieur de ta boucle while, changer des variables et récupérer leur valeur après, elles sont perdues car elles étaient définies dans le sous-shell.

    C'est le même problème avec un "while read" qui lit la sortie d'une autre commande.

    Par contre c'est différent avec les redirections, donc tu pourrais arriver presque au même résultat en jouant avec un tube nommé (man mkfifo):

    #!/bin/sh

    if ! [ -e plop.fifo ];then
    mkfifo plop.fifo
    fi

    cat plop.fifo &

    while true
    do
    echo plop
    exit 1
    done >plop.fifo

    echo fin
    • [^] # Re: http://www.chezmoicamarche.org/

      Posté par  . Évalué à 2.

      merci pour ta réponse.

      j'essayerais de bricoler un truc avec un fifo, ça devrais faire l'affaire :)
    • [^] # Re: http://www.chezmoicamarche.org/

      Posté par  . Évalué à 1.

      La version sans fifo ;)

      #!/bin/bash

      exec 3> >(cat)

      while true
      do
      echo plop
      exit 1
      done >&3

      echo fin
      • [^] # Re: http://www.chezmoicamarche.org/

        Posté par  . Évalué à 1.

        Pas exactement, tu as aussi une fifo ici (ton descripteur 3), la différence c'est qu'ici elle est anonyme. Ça évite de devoir créer un fichier temporaire (ce qui est souvent source de trou de sécurité si ce n'est pas bien fait).
        J'avais pas pensé à ça, mais c'est intéressant, je retiens l'astuce :-)
  • # Le pipe

    Posté par  . Évalué à 3.

    Salut,

    C'est ton pipe "|" qui fait que ton script ne se comporte pas comme tu l'as prévu.
    En effet, le exit te faire sortir du while, et tu te retrouve "dans le pipe".

    Dis moi ce que tu veux faire si tu veux un coup de main.
    • [^] # Re: Le pipe

      Posté par  . Évalué à 2.

      En fait, je m'en doutais par le comportement du truc qui laissait vraiment penser ça, mais je voulais confirmation de mes doutes.

      Pour le problème dans son ensemble (ou presque), je suis dans un while getopts blablabla, ou toutes mes options font appel a des fonctions et certaines étaient récurentes.
      Vu que j'aime pas les trucs récurents dans mes scripts, je les ai sortis du while et là, c le drame :)

      Sinon, le pipe était pour rediriger l'ensemble de mon while dans un tee pour pouvoir laisser la log et afficher la sortie. J'ai trouver ça assez classe de gerer l'ensemble de mes sorties (stdout, stderr + log) avec un | tee $LOG bien placer, mais vu que ça fou le bordel ...

      Maintenant que j'ai confirmation, va falloir ou choisir comment loger mieux (peut-être avec un fifo (merci wismerhill )) ou remettre mes fonctions redondante dans mes options de getopts.

      En bref, je devrais m'en sortir, mais merci pour ta propositions :)
      • [^] # Re: Le pipe

        Posté par  . Évalué à 2.

        Mais sinon, le plus "simple", c'est au lieu de mettre ton pipe sur le while complet, tu le mets sur chaque action qui nescessite ton tee.
        Comme ça, c'est pluss granulaire si tu veux. Tu peux désactiver les logs une par une, au lieu de forcement tout avoir.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.