0

I have a simple python script test.py:

from __future__ import print_function
print("Hello")

I try to redirect the printing to a file, inside a screen session. The following things work:

Without screen:

python test.py > out.txt

With screen, step by step:

screen -S tmp
python test.py > out.txt
exit

However what I really need is not working (out.txt remains empty):

screen -Sdm tmp python test.py > out.txt

After reading a seemingly related question I also tried:

screen -Sdm tmp stdbuf -i0 -o0 -e0 python test.py > out.txt

But it also didn't work.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
BlueSun
  • 3,541
  • 1
  • 18
  • 37

4 Answers4

1

However what I really need is not working (out.txt remains empty):

screen -Sdm tmp python test.py > out.txt

That command works as follows:

  • The shell launches the screen program with standard output redirected to out.txt
  • In the screen session python is run without any output redirection. One might expect that the output of python should eventually be sent to out.txt anyway, because of the output redirection applied to its parent process. However, that doesn't happen since screen does its own management of output streams.

You can solve the problem by making the output redirection happen inside the screen session as follows:

screen -Sdm tmp bash -c "python test.py > out.txt"

This runs under screen the following command:

bash -c "python test.py > out.txt"

which stands for start bash and execute inside it the command "python test.py > out.txt".

Leon
  • 31,443
  • 4
  • 72
  • 97
1

I am not sure of how you could redirect the output externally or how that screen command works, but if modifying that Python program is under your control, what about this solution? You could write something like this at the very beginning of your program:

import sys

class Logger(object):
    def __init__(self, logfile):
        self.terminal = sys.stdout
        self.log = open(logfile, "a")

    def write(self, message):
        self.terminal.write(message)  # This might be optional for you
        self.log.write(message)  

    def flush(self):
        #this flush method is needed for python 3 compatibility.
        #this handles the flush command by doing nothing.
        #you might want to specify some extra behavior here.
        pass    

if len(sys.argv) > 1:  # Just in case no argument was passed to the program
    sys.stdout = Logger(sys.argv[1])

By doing this, you would not need to rewrite every print statement. You would then use your screen command without the > redirection, passing the file as a normal argument:

screen -Sdm tmp python test.py out.txt

Or perhaps you might require quotation marks for this to work:

screen -Sdm tmp python "test.py out.txt"
FernAndr
  • 1,448
  • 1
  • 14
  • 26
0

have you considered using the file read/write ? example:

file = open("path/to/file", "w")
file.write("Hello")
file.close
TuffK
  • 1
  • 1
  • I want to apply this to an already written and large python program. Therefore I want to avoid rewriting every print statement if possible. – BlueSun Aug 03 '17 at 14:16
-2

How about just implementing some logging? Use daiquiri the simplify it.

mohhinder
  • 1
  • 1