Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   output to console and to multiple files (http://www.velocityreviews.com/forums/t399228-output-to-console-and-to-multiple-files.html)

nathan.shair@gmail.com 02-14-2007 10:28 PM

output to console and to multiple files
 
Hello,

I searched on Google and in this Google Group, but did not find any
solution to my problem.

I'm looking for a way to output stdout/stderr (from a subprocess or
spawn) to screen and to at least two different files.

eg.
stdout/stderr -> screen
stdout -> log.out
stderr -> log.err

and if possible
stdout/stderr -> screen and log.txt

3 files from stdout/stderr


Matimus 02-15-2007 12:05 AM

Re: output to console and to multiple files
 
I took a look around and I couldn't find anything either. I will be
keeping an eye on this thread to see if someone posts a more standard
solution. In the mean time though, I will offer up a potential
solution. Duck typing is your friend. If you are only using the write
method of your files, it can be pretty simple to implement a fake file
object to do what you want.

Code:

import sys

class TeeFile(object):
    def __init__(self,*files):
        self.files = files
    def write(self,txt):
        for fp in self.files:
            fp.write(txt)

if __name__ == "__main__":
    outf = file("log.out","w")
    errf = file("log.err","w")
    allf = file("log.txt","w")
    sys.stdout = TeeFile(sys.__stdout__,outf,allf)
    sys.stderr = TeeFile(sys.__stderr__,errf,allf)

    print "hello world this is stdout"
    print >> sys.stderr , "hello world this is stderr"


goodwolf 02-15-2007 12:10 AM

Re: output to console and to multiple files
 
like this?

class Writers (object):

def __init__(self, *writers):
self.writers = writers

def write(self, string):
for w in self.writers:
w.write(string)

def flush(self):
for w in self.writers:
w.flush():

import sys

logfile = open('log.txt', 'w')
sys.stdout = Writers(aya.stdout, file('log.out', 'w'), logfile)
sys.stderr = Writers(aya.stdout, file('log.err', 'w'), logfile)


Gabriel Genellina 02-15-2007 01:52 AM

Re: output to console and to multiple files
 
En Wed, 14 Feb 2007 19:28:34 -0300, nathan.shair@gmail.com
<nathan.shair@gmail.com> escribió:

> I'm looking for a way to output stdout/stderr (from a subprocess or
> spawn) to screen and to at least two different files.


Look at the tee command. If you control the subprocess, and it's written
in Python, using the Python recipes would be easier and perhaps you have
more control.
But if you can't modify the subprocess, you'll have to use tee.

--
Gabriel Genellina


nathan.shair@gmail.com 02-15-2007 03:53 PM

Re: output to console and to multiple files
 
On Feb 14, 5:10 pm, "goodwolf" <Robert.Ka...@gmail.com> wrote:
> like this?
>
> class Writers (object):
>
> def __init__(self, *writers):
> self.writers = writers
>
> def write(self, string):
> for w in self.writers:
> w.write(string)
>
> def flush(self):
> for w in self.writers:
> w.flush():
>
> import sys
>
> logfile = open('log.txt', 'w')
> sys.stdout = Writers(aya.stdout, file('log.out', 'w'), logfile)
> sys.stderr = Writers(aya.stdout, file('log.err', 'w'), logfile)



i've tried simliar methods to this and to what Matimus wrote. I know
it works great when using print statements.
However, I'm looking to find something that will work with the output
from a subprocess, such as from spawn, os.system, os.popen, etc.


nathan.shair@gmail.com 02-15-2007 03:57 PM

Re: output to console and to multiple files
 
On Feb 14, 6:52 pm, "Gabriel Genellina" <gagsl...@yahoo.com.ar> wrote:
> En Wed, 14 Feb 2007 19:28:34 -0300, nathan.sh...@gmail.com
> <nathan.sh...@gmail.com> escribió:
>
> > I'm looking for a way to output stdout/stderr (from a subprocess or
> > spawn) to screen and to at least two different files.

>
> Look at the tee command. If you control the subprocess, and it's written
> in Python, using the Python recipes would be easier and perhaps you have
> more control.
> But if you can't modify the subprocess, you'll have to use tee.
>
> --
> Gabriel Genellina


Tee, the unix function? Or is there a tee that is python?


Matimus 02-15-2007 04:51 PM

Re: output to console and to multiple files
 
On Feb 15, 7:53 am, "nathan.sh...@gmail.com" <nathan.sh...@gmail.com>
wrote:
> On Feb 14, 5:10 pm, "goodwolf" <Robert.Ka...@gmail.com> wrote:
>
>
>
> > like this?

>
> > class Writers (object):

>
> > def __init__(self, *writers):
> > self.writers = writers

>
> > def write(self, string):
> > for w in self.writers:
> > w.write(string)

>
> > def flush(self):
> > for w in self.writers:
> > w.flush():

>
> > import sys

>
> > logfile = open('log.txt', 'w')
> > sys.stdout = Writers(aya.stdout, file('log.out', 'w'), logfile)
> > sys.stderr = Writers(aya.stdout, file('log.err', 'w'), logfile)

>
> i've tried simliar methods to this and to what Matimus wrote. I know
> it works great when using print statements.
> However, I'm looking to find something that will work with the output
> from a subprocess, such as from spawn, os.system, os.popen, etc.


I think you should be able to use my or goodwolf's solution with the
subprocess module. Something like this (untested):

Code:

class TeeFile(object):
    def __init__(self,*files):
        self.files = files
    def write(self,txt):
        for fp in self.files:
            fp.write(txt)

if __name__ == "__main__":
    import sys
    from subprocess import Popen

    command = "whatever you want to run"
    outf = file("log.out","w")
    errf = file("log.err","w")
    allf = file("log.txt","w")
    Popen(
        command,
        stdout = TeeFile(sys.__stdout__,outf,allf),
        stderr = TeeFile(sys.__stderr__,errf,allf)
    )


Matimus 02-15-2007 10:35 PM

Re: output to console and to multiple files
 
On Feb 15, 8:51 am, "Matimus" <mccre...@gmail.com> wrote:
> On Feb 15, 7:53 am, "nathan.sh...@gmail.com" <nathan.sh...@gmail.com>
> wrote:
>
>
>
> > On Feb 14, 5:10 pm, "goodwolf" <Robert.Ka...@gmail.com> wrote:

>
> > > like this?

>
> > > class Writers (object):

>
> > > def __init__(self, *writers):
> > > self.writers = writers

>
> > > def write(self, string):
> > > for w in self.writers:
> > > w.write(string)

>
> > > def flush(self):
> > > for w in self.writers:
> > > w.flush():

>
> > > import sys

>
> > > logfile = open('log.txt', 'w')
> > > sys.stdout = Writers(aya.stdout, file('log.out', 'w'), logfile)
> > > sys.stderr = Writers(aya.stdout, file('log.err', 'w'), logfile)

>
> > i've tried simliar methods to this and to what Matimus wrote. I know
> > it works great when using print statements.
> > However, I'm looking to find something that will work with the output
> > from a subprocess, such as from spawn, os.system, os.popen, etc.

>
> I think you should be able to use my or goodwolf's solution with the
> subprocess module. Something like this (untested):
>
>
Code:

> class TeeFile(object):
>    def __init__(self,*files):
>        self.files = files
>    def write(self,txt):
>        for fp in self.files:
>            fp.write(txt)
>
> if __name__ == "__main__":
>    import sys
>    from subprocess import Popen
>
>    command = "whatever you want to run"
>    outf = file("log.out","w")
>    errf = file("log.err","w")
>    allf = file("log.txt","w")
>    Popen(
>        command,
>        stdout = TeeFile(sys.__stdout__,outf,allf),
>        stderr = TeeFile(sys.__stderr__,errf,allf)
>    )
>



I tried this at lunch and it doesn't work. Some version of this method
may work, but Popen tries to call the 'fileno' method of the TeeFile
object (at least it did on my setup) and it isn't there. This is just
a preemptive warning before someone comes back to let me know my code
doesn't work.


Gabriel Genellina 02-16-2007 12:48 AM

Re: output to console and to multiple files
 
En Thu, 15 Feb 2007 19:35:10 -0300, Matimus <mccredie@gmail.com> escribió:

>> I think you should be able to use my or goodwolf's solution with the
>> subprocess module. Something like this (untested):
>>
>> [code]
>> class TeeFile(object):
>> def __init__(self,*files):
>> self.files = files
>> def write(self,txt):
>> for fp in self.files:
>> fp.write(txt)
>>

>
> I tried this at lunch and it doesn't work. Some version of this method
> may work, but Popen tries to call the 'fileno' method of the TeeFile
> object (at least it did on my setup) and it isn't there. This is just
> a preemptive warning before someone comes back to let me know my code
> doesn't work.


I don't think any Python only solution could work. The pipe options
available for subprocess are those of the underlying OS, and the OS knows
nothing about Python file objects.

--
Gabriel Genellina


nathan.shair@gmail.com 02-16-2007 03:36 PM

Re: output to console and to multiple files
 
On Feb 15, 5:48 pm, "Gabriel Genellina" <gagsl...@yahoo.com.ar> wrote:
> En Thu, 15 Feb 2007 19:35:10 -0300, Matimus <mccre...@gmail.com> escribió:
>
>
>
> >> I think you should be able to use my or goodwolf's solution with the
> >> subprocess module. Something like this (untested):

>
> >> [code]
> >> class TeeFile(object):
> >> def __init__(self,*files):
> >> self.files = files
> >> def write(self,txt):
> >> for fp in self.files:
> >> fp.write(txt)

>
> > I tried this at lunch and it doesn't work. Some version of this method
> > may work, but Popen tries to call the 'fileno' method of the TeeFile
> > object (at least it did on my setup) and it isn't there. This is just
> > a preemptive warning before someone comes back to let me know my code
> > doesn't work.

>
> I don't think any Python only solution could work. The pipe options
> available for subprocess are those of the underlying OS, and the OS knows
> nothing about Python file objects.
>
> --
> Gabriel Genellina


I've tried the subprocess method before without any luck.


Thanks for all your suggestions. I guess it's time to rethink what I
want to do.



All times are GMT. The time now is 10:40 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.