Dawid Fieluba
Dawid Fieluba

Reputation: 1301

How to write to stdout after redirecting FD

Please take a look at this python code below.

so = open('/tmp/test.log', 'a+')
os.dup2(so.fileno(), sys.stdout.fileno())

After executing that piece of code I would like to still have possibility to print something on standard stdout.


I already tried:

print('Foo\n', file=sys.__stdout__)

As according to documentation could be a way to go.

sys.__stdin__
sys.__stdout__
sys.__stderr__

These objects contain the original values of stdin, stderr and stdout at the start of the program. They are used during finalization, and could be useful to print to the actual standard stream no matter if the sys.std* object has been redirected.

But it's not in that case. Its still logging to my test.log file.

Python version: 3.4.8

Any help would be greatly appreciated.

Upvotes: 4

Views: 3087

Answers (1)

Leo K
Leo K

Reputation: 5354

The reason sys.__stdout__ did not work is because you replaced the original stdout's file descriptor with os.dup2(), so any Python file object that is based on it would print to the newly-opened file. The old stdout actually gets closed when you do dup2, so there is no restoring it.

If you want to have all Python code that uses sys.stdout to print to /tmp/test.log, open a new file and assign it to sys.stdout.

sys.stdout = open('/tmp/test.log', 'a+')

The original sys.stdout will remain available as sys.__stdout__.

f you want also to redirect any code that writes directly to sys.stdout.fileno(), including subprocesses that you start with os.system() or subprocess.call(), while keeping access to the original stdout, things get more complex: you would need to dup() stdout first and save that, then use your dup2() call to replace FD 1:

saved_stdout_fd = os.dup(sys.stdout.fileno())
saved_stdout = os.fdopen(saved_stdout_fd,'w')
so = open('/tmp/test.log', 'a+')
os.dup2(so.fileno(), sys.stdout.fileno())

Now sys.stdout goes to your /tmp/test.log and saved_stdout will write to the original stdout.

Upvotes: 8

Related Questions