IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Linux Discussion :

system et redirection sortie standard sous linux


Sujet :

Linux

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut system et redirection sortie standard sous linux
    Bonjour,

    Je suis en train de developper une interface utilisant ncurses. Une de mes fonctionnalites est de pouvoir editer un fichier texte. Pour cela, j'utilise la commande system pour lancer un terminal et lancer un editeur. Seulement voila, lorsque system renvoie une erreur (s'il ne trouve pas le terminal) alors il m'affiche une chaine a l'ecran. C'est ca que je ne veux pas puisqu'utilisant ncurses, ca m'affiche ca n'importe comment.

    voici le bout de code concerné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    void FormScripts::editerFichier(string nomFichier)
    {
    	string terminal = getTerminal();
    	string editeur = getEditeur();
     
    	string commande;
    	if(terminal == "")
    	{
    		commande = editeur + " " + nomFichier;
     
    	}
    	else
    	{
    		commande = terminal + " -e=\"" + editeur + " " + nomFichier + "\"";
    	}
     
    	commande += " > Erreurs.log";
     
    	system(commande.c_str());
    }
    PS: j'ai aussi essayé dup et freopen mais ca me fait toujours la meme chose.

    Comment faire pour empecher system d'afficher des infos à l'ecran ? Et comment les recuperer ?

    Merci

    [EDIT]
    Le fichier Erreurs.log est créé mais il ne contient rien.

    [EDIT2]
    En fait la sortie ne se fait pas sur stdout mais sur stderr. En redirigeant la sortie stderr avec freopen, ca marche. Maintenant je ne sait pas comment remettre la sortie stderr comme avant

  2. #2
    Membre habitué Avatar de galak63
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 126
    Points : 146
    Points
    146
    Par défaut
    je pense que google est ton ami :
    tape "man system"
    Le plus dur dans la mort, c'est qu'on loupe l'apéro ...
    www.usirugby.rf.lv

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    Euh je crois que j'ai passé pas mal de temps sur google deja. Sinon j'aurais pas posté ici.

    Comme je l'ai mis dans mon 2eme edit, j'arrive a rediriger les messages ecris par la commande system par contre je n'arrive pas ensuite a rerediriger les messages d'erreurs vers la sortie stderr comme au debut.
    Je ne vois pas comment faire merci

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    La redirection d'un flux standard se fait avec sa fonction membre rdbuf.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    std::ofstream Errors("Toto.txt");
     
    std::streambuf* OldBuf = std::cerr.rdbuf(Errors.rdbuf());
     
    ...
     
    std::cerr.rdbuf(OldBuf);
    Ensuite j'imagine que comme sous Windows, il existe sous Linux des fonctions pour exécuter un programme sans utiliser system (exec ?).

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 125
    Points : 145
    Points
    145
    Par défaut
    Ensuite j'imagine que comme sous Windows, il existe sous Linux des fonctions pour exécuter un programme sans utiliser system (exec ?).
    oui tu as la serie des execc execl et execv ...

    sinon tu peux peut etre rediriger ta commande dans un fichier ou mieu dans un pipe et de lire l autre bout du pipe

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    Merci pour vos réponses. Je n'ai pas de pc ce week end pour tester. Je testerais ça plus tard.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    std::ofstream Errors("Toto.txt");

    std::streambuf* OldBuf = std::cerr.rdbuf(Errors.rdbuf());

    ...

    std::cerr.rdbuf(OldBuf);
    [EDIT]
    Ca ne marche pas. J'ai l'impression que stderr et cerr ne sont pas du tout liés. Du coup, le message s'affiche toujours. Comment faire en C pour rediriger TEMPORAIREMENT stderr ? (je sais comment rediriger mais pas comment remettre a l'origine une fois mon traitement effectué).

    Merci

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    Voici ce que je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    	FILE* sortie = freopen("Erreurs.log", "w", stderr);
    	if(sortie != NULL)
    	{	
    		int err = system(commande.c_str());
     
    		if(err != 0)
    		{
    	                 // afficher l'erreur contenue dans le fichier
                             // ca ca marche
    		}
    		fclose(sortie);
     
                    // reouvrir la sortie erreur standard
                    // ce que je cherche
    	}
    Ceci me permet de recuperer le message d'erreur dans un fichier donc ok.
    Mon probleme est que je ne sait pas replacer la sortie erreur standard dans son flux.
    Pouvez-vous m'aider ?
    Merci

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Il est trivial de faire des redirections avec boost.process.
    Boost ftw

  10. #10
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    Citation Envoyé par loufoque
    boost.process.
    C'est caché où ??
    J'avais déjà utilisé popen() comme une source pour un boost.iostream, mais ne connaissait pas boost.process.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  11. #11
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Boost ftw

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    Ya pas moyen de le faire sans boost?

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    155
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 155
    Points : 77
    Points
    77
    Par défaut
    Je viens de trouver une discution très intéressante sur un autre forum (en anglais).
    En fait si ton code marche pas Laurent Gomilla c'est parce que cerr n'utilise pas de buffer donc pas de redirection possible de cette facon.

    On connait tous (ou presque) l'operateur > pour rediriger la sortie standard dans un fichier. Ceci redirige donc cout dans un fichier.

    Cependant pour cerr, l'operateur est 2>
    Exemple de commande qui renvoie une erreur et qui la met dans le fichier erreur.txt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
           system("aaaa aaa 2> erreur.txt");
    Merci a tous pour vos reponses. J'ai enfin ma solution!!!

    PS : Voici le lien http://www.velocityreviews.com/forum...6-stdcerr.html

  14. #14
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    En fait si ton code marche pas Laurent Gomilla c'est parce que cerr n'utilise pas de buffer donc pas de redirection possible de cette facon
    C'est tout de même étonnant.

  15. #15
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 279
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 279
    Points : 11 015
    Points
    11 015
    Par défaut
    La solution de Laurent intercepte les messages envoyés à la variable globale std::cerr de l'exécutable courant, pas ceux qui partent sur le canal 2 (stderr) des process invoqués. Il est normal que cela ne réponde pas à la question -- de ce que j'en sais.

    Preuve.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // redirect-iostream.cpp
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
     
    void do_redirect(std::ostream & os, std::string const& dest)
    {
        std::ofstream Errors("Toto.txt");
     
        std::streambuf* OldBuf = os.rdbuf(Errors.rdbuf());
     
     
        os << "Debut" << std::endl;
        std::system(("echo 'toto'"+dest).c_str());
        os << "Fin" << std::endl;
        os.rdbuf(OldBuf);
    }
     
    int main (int argc, char **argv)
    {
        // do_redirect(std::cout, "");
        do_redirect(std::cerr, " > /dev/stderr");
     
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $> ./redirect-iostream 2> titi.txt
    Recommencez avec cout, c'est tout pareil.
    La bufferisation, n'a rien à voir a priori. C'est pour faire des flush automatiquement après chaque insertion, ce qui est sans rapport avec les détournements de canaux des sous-process.

    Amusez-vous aussi à rajouter des (f)printf sur stdout, et stderr. Vous verrez que ce qui est détourné, c'est le stream C++, pas les canaux stdout/stderr.

    Bref,
    On doit pouvoir y arriver avec. Peut-être avec popen, mais c'est moins sûr.

    Re-bref. Mauvais forum => dev linux (faute de dev posix & cie).

    Il peut y avoir des choses dans le code de mutt aussi. Vu qu'il permet de lancer d'autres outils comme vim, ...
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Thread et redirection sortie standard.
    Par cnicolas dans le forum Langage
    Réponses: 1
    Dernier message: 28/02/2010, 08h22
  2. Redirection sortie standard vers widget text
    Par issoram dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 23/01/2009, 17h57
  3. redirection de port sous LINUX
    Par bounns dans le forum Réseau
    Réponses: 1
    Dernier message: 15/10/2007, 18h02
  4. Redirection sortie standard - Problème encoding
    Par schniouf dans le forum Langage
    Réponses: 4
    Dernier message: 12/12/2006, 13h51
  5. rerouter la sortie standard sous AIX
    Par HRS dans le forum Langage
    Réponses: 6
    Dernier message: 10/03/2006, 14h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo