Search code examples
pythonlinuxbashfile-descriptorio-redirection

How can I redirect only part of a stream?


I'm using Python on bash on Linux. I would like to be able to suppress error messages from a particular module, but keep other error messages. An example would probably be the most efficient way to convey what I want:


File: module.py

import sys
sys.stderr.write('Undesired output.\n')

File: script.py

import module
import sys

sys.stderr.write('Desired output.\n')
sys.stdout.write('Desired output.\n')
x = int('a')

Output of running script.py:

$ python script.py
Undesired output.
Desired output.
Desired output.
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    x = int('a')
ValueError: invalid literal for int() with base 10: 'a'

Desired output of running script.py:

$ python script.py
Desired output.
Desired output.
Traceback (most recent call last):
  File "script.py", line 6, in <module>
    x = int('a')
ValueError: invalid literal for int() with base 10: 'a'

I cannot modify module.py, but I must use it. I've tried all kinds of redirects, and opening new file descriptors, but I can't seem to change the file descriptors of the calling shell from within python, so

$ python script.py 2>/dev/null
Desired output.

kills ALL stderr output. Since I know that the module is causing the undesired message, I know exactly which point I want to stop redirecting stderr to /dev/null and start redirecting it to &1, but I can't seem to be able to do it from within Python.

Any advice is much appreciated!


Solution

  • There is an example here in the accepted answer that might help you

    Temporarily Redirect stdout/stderr

    but in your case, it assumes that you could do

    import module
    

    after

    import sys
    

    and after you've redirected stderr in your Python code. Like

    import sys
    
    ... redirect code here
    
    import module
    
    ... code to remove redirect
    

    Don't know if that will break your desired functionality, beyond the redirects.

    Also you're not supposed to stick import statements in the middle of your code, as it violates the PEP8 style guide.