Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 18/02/2011, à 20:54

Levi59

[RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

J'ai ressortis quelques vieux script pour les améliorer avec mes nouvelles notions mais je me heurte à un pitit problème :
Dans l'un de mes scripts, j'effectue un update de la liste des paquets, je redirige stderr sur stdout et je récupère les éventuelles demandes de clé de dépots pour aller les cherchers et les installer.

Mon problème c'est que je veux en même temps afficher l'avancé de la mise à jour des dépôts.
À l'époque, j'ai simplement doublé la commande... (je sais c'est pas bien et en plus c'est lent!)

Auriez-vous une méthode simple pour palier à ce problème?

Edit²
Corrigé avec la solution d'ehmicky!

Voici le script :

#!/bin/bash
# script pour mettre à jour la liste des dépots et automatiquement rajouter les cles manquantes.
#
# Copyright (C) 20 Fev. 2011, Rombeaut Rodolphe
# http://scriptam.over-blog.com/
# Released into the public domain.


{
    key="$(sudo apt-get update 2>&1 >&4 | tee >(grep '[[:alnum:]]\{16\}') >&4)"
} 4>&1

[ -n "$key" ] && {
    echo "Il semble que vous n'avez pas toutes les cles d'authentification. "
    echo "Les clefs GPG sont necessaires pour les depots afin de garantir l'authenticite de la connexion"
    echo ""
    until [ "$question" != "" ]; do
    echo -n "Voulez vous recuperer les cles? (Oui/Non)
"
    read question
        shopt -s nocaseglob
        case "$question" in
          oui | o ) 
              OLDIFS=$IFS
            IFS="
"
            for i in $key; do
                gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-key ${i:(-8)}
                gpg -a --export ${i:(-8)} | sudo apt-key add -
            done
            IFS=$OLDIFS
            sudo apt-get update &&
            [ "$?" != "0" ] &&  { 
                echo ""
                echo "Une erreur s'est produite" 
                exit 1 
            }
            echo ok ;;
        
          non | n )
            echo "Pas de recuperation de(s) la(les) cle(s).";;        
          * )
            echo "reponse erronee"
            question=""
        esac
        shopt -u nocaseglob
    done
} || {
    echo "Mise a jour des depots effectuee!"
}
exit 0

EDIT: Petite mise à jour du code...

Dernière modification par Levi59 (Le 21/02/2011, à 17:37)

Hors ligne

#2 Le 19/02/2011, à 01:42

mjdon

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Je suis un peu novice en script mais a ta place, je ferais:

sudo apt-get update 2>error.txt >output.txt
key=`cat error.txt | grep '[0-9A-Z]\{16\}'` 
...
...
rm error.txt output.txt

Evidement, je n'ai rien testé :-) Qu'est ce que tu en penses?

Hors ligne

#3 Le 19/02/2011, à 01:52

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

J'aimerais autant éviter l'usage d'un fichier temporaire si c'est possible, d'autant que durant l'update, on a droit à des infos sur la vitesse de connexion pendant le téléchargement et que j'aimerais conserver cet affichage...

Dernière modification par Levi59 (Le 19/02/2011, à 01:53)

Hors ligne

#4 Le 19/02/2011, à 05:43

wido

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Pour l'avancer des mises à jour tu peux utiliser ça: http://www.theiling.de/projects/bar.html

Hors ligne

#5 Le 19/02/2011, à 08:49

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

C'est un script supplémentaire à installer... Je garde ça à l'esprit car ça pourrais me servir mais tout ce que j'aimerais c'est conserver l'affichage classique tout en récupérant les messages de clé manquante surtout pour voir d'éventuelles autres erreurs.

Edit : Tout ça c'est parce que j'utilise ce script chez les nouveaux linuxiens qui choisissent des distributions un peu moins user-friendly que ubuntu ou bien veulent comprendre un peu mieux le système... Je leur montre que un peu de bash, ça peut simplifier la vie (comment ajouter manuellement les dépôts et les clés puis via apt-add-repository pour ceux qui ont puis via mon script), ça peut être dangereux (petits exemples de commande) et comment utiliser un script téléchargé (en console et en graphique).
Donc du coup ils peuvent installer des nouveaux dépôts, lancer ce script et faire l'update et se voir proposer d'installer les clés si nécessaire. Mais si je n'ai pas de sortie pour afficher les éventuels problème, ils risquent par exemple de ne pas voir une mauvaise connexion ou une quelconque autre erreur.

Et puis je l'utilise aussi sous debian... ^^

Dernière modification par Levi59 (Le 19/02/2011, à 09:01)

Hors ligne

#6 Le 20/02/2011, à 12:13

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Pour l'instant j'ai mis un message d'attente...

Dernière modification par Levi59 (Le 20/02/2011, à 12:53)

Hors ligne

#7 Le 20/02/2011, à 15:32

ehmicky

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

En fait si je comprends bien, tu veux :
   - exécuter apt-get update (une seule fois)
   - rediriger son stdout vers le terminal
   - rediriger son stderr vers le terminal, mais aussi l'utiliser comme input d'un grep.
C'est ça ?


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#8 Le 20/02/2011, à 18:01

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Exactement! Pour l'instant je n'ai pas d'affichage de la mise à jour et je trouverais ça plus pratique de voir ce qui se passe en temps réel.

Hors ligne

#9 Le 20/02/2011, à 18:32

ehmicky

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

{
    key="$(sudo apt-get update 2>&1 >&4 | tee >(grep '[[:alnum:]]\{16\}') >&4)"
} 4>&1

Ca marche peut-être (j'ai pas de Linux pour tester), mais en tout cas il doit y avoir plus simple.
(en tout cas key ne sera initialisé qu'une fois apt-get update terminé ; pour avoir du vrai temps réel, faut peut-être passer par une named pipe ou un coproc)

Dernière modification par ehmicky (Le 20/02/2011, à 18:34)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#10 Le 20/02/2011, à 18:38

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Bonsoir,

Je n'ai pas lu ton script. Mais d'après ton approbation aux questions d'ehmicky, ceci devrait faire l'affaire :

apt-get update 2> >(tee >(grep '[0-9A-Z]\{16\}' - > errors.txt))

ne connaissant pas ce que tu souhaites réaliser avec les lignées filtrées avec, je les redirige vers le fichier errors.txt.

On pourrait également procéder ainsi :

apt-get update 2> >(while read;
do
  echo "${REPLY}"
  [[ ${REPLY} =~ [0-9A-Z]\{16\} ]] && echo "${REPLY}" > errors.txt
done)

je n'ai pas testé mais en cas d'erreur, je pense qu'ehmicky saura corriger wink


-- Lucid Lynx --

Hors ligne

#11 Le 20/02/2011, à 18:40

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

@ ehmicky Ça fonctionne! Merci à toi!
Pour le vrai temps réel, j'entendais par là afficher les infos de mise à jours et les avancement en temps réel et non pas uniquement à 100%. Le traitement des erreurs se fait de toute manière uniquement après la fin de la mise à jour.

Je laisse ouvert pour peut être d'autres méthodes.

Petite question: je suis pas sûr de comprendre l'utilisation de tee (notamment le >) et la redirection avant la pipe.

Edit je suis pas assez rapide ^^

Pour la version de Totor, je n'ai pas essayé mais j'aimerais me passer de fichier temporaire comme le error.txt mais merci de proposer. wink

Dernière modification par Levi59 (Le 20/02/2011, à 19:01)

Hors ligne

#12 Le 20/02/2011, à 19:14

ehmicky

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

@Totor : Levy voulait aussi que la variable key soit initialisé avec l'output de grep. J'étais sûr que tu aurais mieux, redirections == Totor smile
@Levy : En fait, tu pourrais prendre la solution de Totor,mais rediriger vers un coproc plutôt qu'un fichier régulier, et tu lirais ce coproc plutôt que d'utiliser une variable key. Ca te permettrait d'avoir du vrai temps réel si c'est une de tes priorité.
Sinon pour les redirections sur mon précédents posts, elles s'exécutent du dehors vers le dedans, depuis la gauche vers la droite. Donc, cela fait que le subshell exécute dans l'ordre :

Subshell global :
4>&1 : fd4 est créé comme une copie de stdout (il pointe donc vers le terminal), pour ce qui est englobé par les crochets.
$( ) : key est initialisé avec le stdout de ce qui est dans le $( )

Subshell de apt-get update :
| : stdout est redirigé vers stdin du subshell de tee
2>&1 : stderr copie stdout, et est donc redirigé vers le stdin du subshell de tee
>&4 : stdout copie fd4, et est donc redirigé vers le terminal et non plus vers le stdin du subshell de tee

Subshell de tee :
Son input vient donc du stderr du subshell de apt-get update
>&4 : stdout copie fd4, et est donc redirigé vers le terminal
tee : le flux venant de stdin est copié vers stdout (donc vers le terminal) ainsi que vers l'input de >( )

Subshell de grep :
L'input de grep vient de tee, dont l'input vient lui-même du stderr de apt-get update. L'output de grep initialise key (à cause de $( ))

Résultat : apt-get update envoie son stdout vers le terminal (via fd4) et son stderr dans la pipe. La pipe nourrit tee qui envoie celui-ci à la fois vers le terminal (via fd4) et vers l'input de grep. L'output de grep initialise key.

Edit : ok, donc si je comprends bien tu as juste besoin de connaître l'avancement de apt-get update (d'où le fait de l'imprimer sur stdout), mais tu n'as besoin de connaître l'output de grep en temps réel, puisque le test qui suit ("grep a-t-il imprimé quelque chose ou non") exige que grep et apt-get update se soient terminés. Donc pas besoin de coproc ou named pipe, c'est ça ?

Dernière modification par ehmicky (Le 20/02/2011, à 19:35)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#13 Le 20/02/2011, à 19:42

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Whaaah.... yikes

Va me falloir digérer tout ça! ^^
Merci pour tes explications, je pourrais m'améliorer!
[HS] J'ai commencé à apprendre le C pour un stage de gîtologie (je sais c'est pas vraiment en rapport) et je dois dire que j'ai été agréablement surpris de voir les ressemblances dans la syntaxe et les principes de fonctionnement avec le Shell bash. Du coups je vous remercie parce que c'est en grande partie grâce à vos contributions et vos conseils sur le forum que je me suis autant amélioré en programmation![/HS]

Hors ligne

#14 Le 20/02/2011, à 20:23

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

ehmicky a écrit :

ok, donc si je comprends bien tu as juste besoin de connaître l'avancement de apt-get update (d'où le fait de l'imprimer sur stdout), mais tu n'as besoin de connaître l'output de grep en temps réel, puisque le test qui suit ("grep a-t-il imprimé quelque chose ou non") exige que grep et apt-get update se soient terminés. Donc pas besoin de coproc ou named pipe, c'est ça ?

Ouep! C'est ça

Je me doute que le terme "temps réel" n'est peut être pas parfaitement adapté à ce cas car ce serait plutôt pour désigner un traitement sur un flux constant, mais je n'avais pas d'autre terme.

Hors ligne

#15 Le 20/02/2011, à 20:59

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Re,

Comme indiqué plus haut, je n'avais pas lu le script. C'est chose faite et voilà donc une solution appropiée :

tee $(tty) < <( sudo apt-get update 2>&1 >$(tty)) | grep -q '[[:alnum:]]\{16\}' && echo "Mise a jour des depots effectuee!" || {
# traitement lorsque y'a pas de clefs
}

Par contre, dès lors que tu effectues un traitement avec les sorties standard et d'erreur pour les réafficher ensuite, tu perds l'ordre ...
Typiquement, la sortie d'erreur sera affichée en dernier dans notre cas.


-- Lucid Lynx --

Hors ligne

#16 Le 20/02/2011, à 22:01

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Ma variable $key est remplacé par quoi dans ton exemple?
Je ne connaissais pas la variable $(tty) mais par déduction, corrigez moi si je me trompe, je suppose que c'est en quelque sorte la zone d'affichage du terminal (excuse moi si les termes sont mal choisis), donc ma question serait comment traiter le retour dans le cas où une clé est manquante?

Hors ligne

#17 Le 20/02/2011, à 22:12

FRUiT

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Tape 'tty' dans ta console tu verras le résultat.


Neon Suite by FRUiT (kde4.6) [url]http://[Merci de relire les règles]/yzm7cee[/url]
"Pour la carotte, le lapin est la plus parfaite incarnation du mal" (R. Sheckley)
clean

Hors ligne

#18 Le 20/02/2011, à 22:42

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Déjà fait, ça donne ça

rombeaut@DebianDesktop:~$ tty
/dev/pts/0

Hors ligne

#19 Le 20/02/2011, à 22:44

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Levi59 a écrit :

Ma variable $key est remplacé par quoi dans ton exemple?

key="$(tee $(tty) < <( sudo apt-get update 2>&1 >$(tty)) | grep -o '[[:alnum:]]\{16\}')" && echo "Mise a jour des depots effectuee!" || {
# traitement lorsque y'a pas de clefs
# la variable "key" contient les clefs
}

Dernière modification par Totor (Le 20/02/2011, à 22:45)


-- Lucid Lynx --

Hors ligne

#20 Le 20/02/2011, à 23:07

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

@Totor
J'ai testé ton code et quoi qu'il arrive, il renvoi le message à afficher en cas d'erreur et réaffiche la commande au début.
Ici un update sans problème : (j'ai tronqué l'inutile pour plus de lisibilité)

rombeaut@DebianDesktop:~$ key="$(tee $(tty) < <( sudo apt-get update 2>&1 >$(tty)) | grep -o '[[:alnum:]]\{16\}')" && echo "Mise a jour des depots effectuee!" || echo probleme
key="$(tee $(tty) < <( sudo apt-get update 2>&1 >$(tty)) | grep -o '[[:alnum:]]\{16\}')" && echo "Mise a jour des depots effectuee" || echo probleme
Atteint http://ftp.fr.debian.org wheezy Release.gpg                            
[...]       
Atteint http://ftp.fr.debian.org wheezy/non-free i386 Packages/DiffIndex
8 120 o réceptionnés en 19s (427 o/s)
Lecture des listes de paquets... Fait
probleme

Hors ligne

#21 Le 21/02/2011, à 09:37

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Ce n'est pas ce que tu voulais ?
- Avoir les traces (sortie standard et sortie d'erreur) de la commande tout en récupérant les clefs manquantes ?


-- Lucid Lynx --

Hors ligne

#22 Le 21/02/2011, à 10:48

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Oui bien sûr mais pour l'exemple précédent, en reprenant texto le code (j'ai juste changé le commentaire par un echo) et avec un update normal, je devrais avoir comme message de fin "Mise a jour des depots effectuee!" alors que j'ai "problème" qui correspond à un problème de clé.

Je n'ai pas encore essayé de le résoudre mais je crois que le problème viens du test... Je n'ai pas de Linux sous la main pour essayer donc dès que c'est possible, je dis quoi.

Dernière modification par Levi59 (Le 21/02/2011, à 14:49)

Hors ligne

#23 Le 21/02/2011, à 11:34

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

N'étant plus sous une "debian's like", je n'ai plus apt-get et j'ai donc testé avec les exemples suivants :

$ key="$(tee $(tty) < <( { echo "1"; echo "4" >&2; }  2>&1 >$(tty)) | grep -o '4')" && echo "Mise a jour OK" || echo "Pb"
1
4
Mise a jour OK
$ key="$(tee $(tty) < <( { echo "1"; echo "3" >&2; }  2>&1 >$(tty)) | grep -o '4')" && echo "Mise a jour OK" || echo "Pb"
1
3
Pb

Je n'ai pas vérifié l'ERE du grep donné par ehmicky.. regarde de ce côté !
note : essaie également en supprimant l'option -o de grep !


-- Lucid Lynx --

Hors ligne

#24 Le 21/02/2011, à 14:46

Levi59

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

Je viens de trouver le temps de vérifier sous debian.

En fait l'erreur viens du fait que si il n'y a pas d'erreur, $key ne contient rien (une ligne vide en fait) alors que si il y a une erreur de clé, le(s) nombre(s) sont listés dans $key. Jusque là c'est logique.
Mais le test fonctionne donc à l'envers sous cette forme.

si $key non vide(=erreur) && echo "mise à jour ok" || { erreur donc traitement }

devrais donc plutôt être :

si $key non vide(=erreur) && { erreur donc traitement } || echo "mise à jour ok"

Je pense que ceci est donc la cause du problème. Dites moi si je me trompe.

Dernière modification par Levi59 (Le 21/02/2011, à 14:48)

Hors ligne

#25 Le 21/02/2011, à 15:26

Totor

Re : [RÉSOLU] Afficher la sortie d'une commande et la stocker en même temps

arg, t'as "partiellement" raison.
Là où tu as raison : je fais le test à l'envers ...
Là où tu n'as pas totalement raison : le test ne s'effectue pas sur le contenu de la variable key mais sur le statut retourné par l'affectation de la variable key.

Du coup, il faut inverser le test (via l'utilisation de ! en début de ligne) :

! key="$(tee $(tty) < <( sudo apt-get update 2>&1 >$(tty)) | grep -o '[[:alnum:]]\{16\}')" && echo "Mise a jour des depots effectuee!" || echo probleme

-- Lucid Lynx --

Hors ligne