redirecting stdout to a file as well as screen

Discussion in 'Python' started by SamG, Apr 12, 2007.

  1. SamG

    SamG Guest

    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).
     
    SamG, Apr 12, 2007
    #1
    1. Advertising

  2. SamG

    Ant Guest

    On Apr 12, 8:14 am, "SamG" <> wrote:
    > 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
     
    Ant, Apr 12, 2007
    #2
    1. Advertising

  3. En Thu, 12 Apr 2007 04:14:32 -0300, SamG <> escribió:

    > 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

    --
    Gabriel Genellina
     
    Gabriel Genellina, Apr 12, 2007
    #3
  4. SamG

    SamG Guest

    On Apr 12, 1:00 pm, "Gabriel Genellina" <>
    wrote:
    > En Thu, 12 Apr 2007 04:14:32 -0300, SamG <> escribió:
    >
    > > 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
    >
    > --
    > Gabriel Genellina


    This is only creating an out.log file and all the stdout and stderr
    are logged there.
     
    SamG, Apr 12, 2007
    #4
  5. SamG

    SamG Guest

    On Apr 12, 12:40 pm, "Ant" <> wrote:
    > On Apr 12, 8:14 am, "SamG" <> wrote:
    >
    > > 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!
     
    SamG, Apr 12, 2007
    #5
  6. SamG

    7stud Guest

    On Apr 12, 3:35 am, "SamG" <> wrote:
    > On Apr 12, 12:40 pm, "Ant" <> wrote:
    >
    >
    >
    > > On Apr 12, 8:14 am, "SamG" <> wrote:

    >
    > > > 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!


    Try:

    log_file = open("out.log", "w")
     
    7stud, Apr 12, 2007
    #6
  7. On 2007-04-12, SamG <> wrote:
    > On Apr 12, 12:40 pm, "Ant" <> wrote:
    >> On Apr 12, 8:14 am, "SamG" <> wrote:
    >>
    >> > 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.

    > print "Hello"
     
    Antoon Pardon, Apr 12, 2007
    #7
  8. En Thu, 12 Apr 2007 06:01:18 -0300, SamG <> escribió:

    > On Apr 12, 1:00 pm, "Gabriel Genellina" <>
    > wrote:
    >> En Thu, 12 Apr 2007 04:14:32 -0300, SamG <> escribió:
    >>
    >> > 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).

    >>
    >> class Tee(file):
    >> others = ()
    >>
    >> def write(self, data):
    >> file.write(self, data)
    >> for f in others:
    >> f.write(data)
    >>

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


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

    --
    Gabriel Genellina
     
    Gabriel Genellina, Apr 12, 2007
    #8
  9. SamG

    SamG Guest

    On Apr 12, 3:16 pm, "Gabriel Genellina" <>
    wrote:
    > En Thu, 12 Apr 2007 06:01:18 -0300, SamG <> escribió:
    >
    >
    >
    > > On Apr 12, 1:00 pm, "Gabriel Genellina" <>
    > > wrote:
    > >> En Thu, 12 Apr 2007 04:14:32 -0300, SamG <> escribió:

    >
    > >> > 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).

    >
    > >> class Tee(file):
    > >> others = ()

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

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

    >
    > Sorry, `for f in others:` should read `for f in self.others:`
    >
    > --
    > 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 :)
     
    SamG, Apr 12, 2007
    #9
  10. En Thu, 12 Apr 2007 07:23:43 -0300, SamG <> escribió:

    >> >> > 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).

    >>
    >> >> class Tee(file):
    >> >> others = ()

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

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

    >>
    >> 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 :)


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

    --
    Gabriel Genellina
     
    Gabriel Genellina, Apr 12, 2007
    #10
  11. SamG

    SamG Guest

    On Apr 12, 3:42 pm, "Gabriel Genellina" <>
    wrote:
    > En Thu, 12 Apr 2007 07:23:43 -0300, SamG <> escribió:
    >
    >
    >
    > >> >> > 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).

    >
    > >> >> class Tee(file):
    > >> >> others = ()

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

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

    >
    > >> 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 :)

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



    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.
     
    SamG, Apr 12, 2007
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Douwe
    Replies:
    1
    Views:
    5,676
    Mike Schilling
    Jan 12, 2004
  2. Elad
    Replies:
    0
    Views:
    422
  3. =?gb2312?B?yMvR1MLkyNXKx8zs0cSjrM37vKvM7NHEsru8+7z

    Issue of redirecting the stdout to both file and screen

    =?gb2312?B?yMvR1MLkyNXKx8zs0cSjrM37vKvM7NHEsru8+7z, May 28, 2007, in forum: Python
    Replies:
    5
    Views:
    384
    =?gb2312?B?yMvR1MLkyNXKx8zs0cSjrM37vKvM7NHEsru8+7z
    May 29, 2007
  4. comp.lang.ruby
    Replies:
    4
    Views:
    289
    Gary Wright
    Jan 11, 2010
  5. jonathan
    Replies:
    6
    Views:
    162
    Jay Tilton
    Nov 25, 2003
Loading...

Share This Page