Edit: étant donné qu'il semble qu'il n'y a pas de solution, ou je suis en train de faire quelque chose de manière non-standard que personne ne le sait - je vais revoir ma question, également, de se poser: Quelle est la meilleure façon d'effectuer la journalisation quand un python application est de faire beaucoup d'appels système?
Mon application a deux modes. En mode interactif, je veux toutes les sorties pour aller à l'écran ainsi que dans un fichier journal, y compris la sortie de tous les appels système. En mode démon, toutes les sorties se passe dans le journal. Mode démon fonctionne très bien en utilisant le système d'exploitation.dup2(). Je ne peux pas trouver un moyen de "tee" toutes les sorties à un journal en mode interactif, sans modification de chaque appel système.
En d'autres termes, je veux la fonctionnalité de la ligne de commande 'tee' pour toute sortie générée par un python application, y compris le système d'appel de sortie.
Pour clarifier:
Pour rediriger toutes les sorties que je fais quelque chose comme ça, et il fonctionne très bien:
# open our log file
so = se = open("%s.log" % self.name, 'w', 0)
# re-open stdout without buffering
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
# redirect stdout and stderr to the log file opened above
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
La bonne chose à ce sujet est qu'il ne nécessite aucune spéciale d'impression des appels à partir du reste du code. Le code s'exécute également de certaines commandes shell, donc c'est agréable de ne pas avoir à traiter avec chacun de leur production individuelle.
Simplement, je veux faire la même chose, sauf en double au lieu de redirection.
À première vue, je pensais qu'il suffit d'inverser le dup2 de travail. Pourquoi n'est-ce pas? Voici mon test:
import os, sys
### my broken solution:
so = se = open("a.log", 'w', 0)
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
os.dup2(sys.stdout.fileno(), so.fileno())
os.dup2(sys.stderr.fileno(), se.fileno())
###
print "kljhf sdf"
os.spawnve("P_WAIT", "/bin/ls", ["/bin/ls"], {})
os.execve("/bin/ls", ["/bin/ls"], os.environ)
Le fichier ".journal" doit être identique à ce qui était affiché sur l'écran.