2014-06-18 2 views
1

J'essaie de rediriger stdout vers un fichier de manière permanente, mais tous les exemples que je peux trouver à propos de cela impliquent de le faire dans un let ou dans un fichier open-open en utilisant la sortie standard global. Y at-il un moyen de faire une redirection large application?Rediriger définitivement stdout vers un fichier en Common Lisp (CCL)

EDIT: Voici comment j'ai essayé de faire la redirection avec la sortie standard:

(Setf *log* (open "/Users/Mike/Desktop/some.txt" :direction :output :if-exists :append)) 
(Setf *standard-output* *log*) 
(print "Test") 

Cette sortie arrête au REPL mais rien ne montre dans le fichier (qui n'existe et est vu par probe-file) de l'appel d'impression.

EDIT: J'ai essayé d'utiliser la fonction Dribble:

(Dribble "/Users/Mike/Desktop/some.txt") 

(format t "hello") 

Mais je reçois l'erreur suivante:

Error: There is no applicable method for the generic function: #STANDARD-GENERIC-FUNCTION CCL::STREAM-SET-COLUMN #x30200006557F when called with arguments: (# 0) While executing: #, in process Listener(11). Type cmd-/ to continue, cmd-. to abort, cmd-\ for a list of available restarts. If continued: Try calling it again Type :? for other options.

+0

Est-ce que '(setf * standard-output * ...)' ne fonctionne pas? –

+0

@JoshuaTaylor Oui, j'ai ajouté ce que j'ai essayé à mes questions. Il arrête la sortie au repel mais rien n'apparaît dans le fichier. – Mike2012

+0

Um, cela ne montre rien qui devrait produire une sortie si. Quelles formes, après cela, ne produisent pas de sortie? Faites-vous quelque chose avec plusieurs threads? (Par exemple, si vous utilisez SLIME, vous utilisez peut-être plusieurs threads sans le savoir.) Vous pouvez uniquement définir \ * standard-output * sur \ * log * dans l'un de ces threads.) –

Répondre

5

Je pense que votre problème a à voir avec mise en mémoire tampon. Essayez force-output:

(force-output *log*) 

Notez que les flux de fermeture automatique des tampons Flushes et Lisps habituellement des flux proches sur la sortie normale, donc rien perdu est en fait, il faut juste le temps d'apparaître sur le disque.

De plus, veuillez noter que l'interaction REPL Common Lisp est effectuée sur many different stream variables, et non sur une seule (bien que nombre d'entre eux soient des alias d'autres).

En fait, si vous souhaitez enregistrer le journal de votre session (c'est-à-dire conserver le REPL sur l'écran et enregistrer la transcription dans un fichier), le service standard est fourni par dribble - essayez-le!

+0

Merci! Cela fonctionne mais un problème que j'ai toujours est que j'ai besoin de vider le tampon avant que les choses soient réellement poussées vers le fichier. Je voudrais utiliser cette fonctionnalité pour la consignation des erreurs et ce travail fonctionne correctement pour l'erreur détectée (parce que je pourrais vider la mémoire tampon du gestionnaire d'erreurs) mais s'il y avait une erreur non interceptée, elle pourrait être complètement oubliée dans le journal. Y a-t-il un moyen de forcer la sortie standard? – Mike2012

+1

Les tampons sont rincés 'close', donc rien n'est perdu. Je vous recommande vraiment d'essayer dribble avant de commencer avec des solutions maison. – sds

+0

Merci encore pour tous vos conseils. J'ai essayé d'utiliser dribble mais j'ai une erreur (j'ai posté dans un autre edit). Je suppose que cela pourrait avoir quelque chose à voir avec l'implémentation spécifique de dribble, à moins que j'utilise dribble faux? Il semble que vous venez de passer un chemin vers un fichier journal. – Mike2012