2010-07-09 4 views
0

Je lis environ freopen pour rediriger tout printf dans un fichier, mais je voudrais que la sortie soit imprimée sur l'écran aussi bien. Y at-il un moyen facile de rediriger le printfs vers un fichier et obtenir la sortie de la ligne cmd?Sortie dans le fichier et la ligne de commande

Merci!

+0

Ceci est un repost de: http://stackoverflow.com/questions/418896/how-to-redirect-output-to-a-file-and-stdout – MasterHD

+0

@MasterHD, vous avez raison. probablement je n'ai pas cherché assez à l'époque. – Framester

Répondre

0

en dehors du programme, utilisez « T »:

# echo foo | tee foo.txt 
foo 
# cat foo.txt 
foo 

En fait, vous pourriez popen() un canal à un tee-shirt qui écrit le fichier, bien que ce système lourd. Quelque chose à cet effet:

FILE *stream_to_write_to = popen("tee filename.txt"); 
fprintf(stream_to_write_to, "goes to filename.txt and stdout\n"); 

Je suis curieux de voir s'il y a un moyen rapide de-C de le faire, parce qu'à un certain niveau, cela implique la copie de données. Il est facile d'écrire deux fichiers pour écrire au même endroit, utilisez dup() ou autre, mais le contraire est plus compliqué. Cela peut impliquer de pousser un module (l'exemple courant est "connld" sur un flux), bien que honnêtement, je n'ai jamais vu cela utilisé, donc j'aimerais voir un exemple de code de travail moi-même.

La meilleure référence que je puisse donner est «Programmation avancée dans l'environnement UNIX» de Stevens.

Mise à jour:

Pour parler au commentaire de R ci-dessous, la solution ci-dessus est un peu plus lourde version de juste fourchette/exec-ing et la réorientation de la poignée de l'enfant quelque part d'autre. Les deux vont résoudre le problème, bien que je préfère ce qui précède, car il est plus facile à nettoyer, mais honnêtement, les deux solutions sont assez lourdes. Fork() n'est pas une fonction légère. Si l'esprit de la question est de le faire sans fork/exec, alors je ne suis pas sûr, j'aimerais aussi savoir. Si fork/exec est correct, alors l'utiliser directement ou utiliser popen() le piratera.

+0

Utilisez 'popen' et fork votre propre processus enfant qui imite' tee' et écrit à la fois sur l'ancien stdout et le fichier choisi. Ne pas exec un binaire externe; implémentez simplement la fonctionnalité "tee" dans votre propre programme. –

+0

@r: vous pouvez le faire aussi, mais vous devrez aussi attendre le pid et le nettoyer, plutôt que de fermer le flux. J'admets que c'est vraiment lourd - ainsi que fork/exec pour ça. Je pense que l'esprit de la question est de copier des données sans fourchette, donc ce n'est pas une réponse complètement satisfaisante pour moi.Connaissez-vous les modules de flux par hasard? C'est un coin incrusté de cobweb de programmation Unix que je n'ai pas étudié auparavant. :-) – eruciform

+1

Linux 2.6.17 introduit tee (2) et splice (2), qui peut être utilisé pour implémenter tee (1) efficacement. – ninjalj

0

freopen n'est pas une bonne idée pour rediriger stdout. Il ne réutilisera pas nécessairement le même numéro de descripteur de fichier, de sorte que les processus enfants n'hériteront pas de la nouvelle sortie stdout (ou peuvent se retrouver sans stdout). Il est préférable d'utiliser open puis dup2 ou close(0) puis open pour créer une nouvelle cible pour stdout.

1

Une autre alternative consiste à écrire une fonction qui fonctionne comme printf, mais dirige la sortie à deux endroits différents. Par exemple:

#include <stdio.h> 
#include <stdarg.h> 

void printf2(FILE *fp, char *format, ...) 
{ 
    va_list ap; 
    va_list ap2; 

    va_start(ap, format); 
    va_copy(ap2, ap); 

    vfprintf(fp, format, ap); 
    va_end(ap); 

    vprintf(format, ap2); 
    va_end(ap2); 
} 

Vous pouvez ensuite appeler printf2 de la même façon que vous appelleriez fprintf, et la sortie ira à la fois le pointeur passé dans FILE et stdout:

FILE *fp = fopen("/tmp/foo", "w"); 
printf2(fp, "This is a test.\n"); 

Cette approche n'utilise pas de sous-processus ou de tuyaux, et peut être généralisé à plusieurs pointeurs de fichiers, si nécessaire.

+0

+1: sympa! j'ai oublié ça. oui, c'est probablement le plus simple. – eruciform

+0

Salut, merci pour la réponse, mais à la fin je l'ai trouvé plus facile à utiliser «tee». – Framester

Questions connexes