redirecting stdout to a file as well as screen

S

SamG

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).
 
A

Ant

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).

One way would be to create a custom class which has the same methods
as the file type, and held a list of file-like objects to write to.
e.g.

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)
def writelines(self, str_list):
#etc

Then assign stdout and stderr to a new instance of one of these
objects:

mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

HTH
 
G

Gabriel Genellina

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).

A very minimal example:

import sys

class Tee(file):
others = ()

def write(self, data):
file.write(self, data)
for f in others:
f.write(data)

tee = Tee(r"c:\temp\output.log","wt")
tee.others = [sys.stdout, sys.stderr]
sys.stdout = sys.stderr = tee

print dir(sys)
sys.foo # error
 
S

SamG

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).

A very minimal example:

import sys

class Tee(file):
others = ()

def write(self, data):
file.write(self, data)
for f in others:
f.write(data)

tee = Tee(r"c:\temp\output.log","wt")
tee.others = [sys.stdout, sys.stderr]
sys.stdout = sys.stderr = tee

print dir(sys)
sys.foo # error

This is only creating an out.log file and all the stdout and stderr
are logged there.
 
S

SamG

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).

One way would be to create a custom class which has the same methods
as the file type, and held a list of file-like objects to write to.
e.g.

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)
def writelines(self, str_list):
#etc

Then assign stdout and stderr to a new instance of one of these
objects:

mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

HTH



I have written this....

import sys

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)

log_file='out.log'
mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

print "Hello"

And i get this when i run the porgram.

HelloHelloTraceback (most recent call last):
Traceback (most recent call last):

Kindly advice!
 
7

7stud

One way would be to create a custom class which has the same methods
as the file type, and held a list of file-like objects to write to.
e.g.
class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist
def write(self, str):
for f in self.filelist:
f.write(str)
def writelines(self, str_list):
#etc
Then assign stdout and stderr to a new instance of one of these
objects:
mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

I have written this....

import sys

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)

log_file='out.log'
mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

print "Hello"

And i get this when i run the porgram.

HelloHelloTraceback (most recent call last):
Traceback (most recent call last):

Kindly advice!

Try:

log_file = open("out.log", "w")
 
A

Antoon Pardon

How could i make, from inside the program, to have the stdout and
stderr to be printed both to a file as well the terminal(as usual).

One way would be to create a custom class which has the same methods
as the file type, and held a list of file-like objects to write to.
e.g.

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)
def writelines(self, str_list):
#etc

Then assign stdout and stderr to a new instance of one of these
objects:

mc = multicaster([sys.stdout, sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc

HTH



I have written this....

import sys

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)

log_file='out.log'

log_file is not a file but a string, So when you reach the
write method in your multicaster you get an atttribute error
because a string has no write method
mc = multicaster([sys.stdout, sys.stderr, log_file])

Since sys.stdout and sys.stderr usually both refer to
the terminal, this will result in your output appearing
twice on the terminal
sys.stdout = mc
sys.stderr = mc

Maybe you are better of leaving sys.stderr as it is,
at least until you are sure your multicaster itself
is working as it should.
 
S

SamG

En Thu, 12 Apr 2007 06:01:18 -0300, SamG <[email protected]> escribió:





Sorry, `for f in others:` should read `for f in self.others:`


Does not make difference, does this work for you? Im working on linux.
But this code looks portable except for the file path :)
 
G

Gabriel Genellina

Does not make difference, does this work for you? Im working on linux.
But this code looks portable except for the file path :)

Yes. And it's rather similar to your other example... Omit sys.stderr as
Antoon Pardon suggested.
 
S

SamG

En Thu, 12 Apr 2007 07:23:43 -0300, SamG <[email protected]> escribió:





Yes. And it's rather similar to your other example... Omit sys.stderr as
Antoon Pardon suggested.


Thanks people i have got it working now...

with this program!

#END
import sys

class multicaster(object):
def __init__(self, filelist):
self.filelist = filelist

def write(self, str):
for f in self.filelist:
f.write(str)

log_file=open('out.log','w')
mc = multicaster([sys.stderr, log_file])
sys.stdout = mc
sys.stderr = mc
sys.stdout.write( "Mojozoox\n")
sys.stderr.write( "Hello\n")
#END

works perfect for my needs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top