Redirect stdout from python for C calls

≡放荡痞女 提交于 2019-11-28 11:13:14

I've written below a few additional comments that should make clearer what it's going on inside the redirect_stdout function:

def redirect_stdout():
    print "Redirecting stdout"
    sys.stdout.flush() # <--- important when redirecting to files

    # Duplicate stdout (file descriptor 1)
    # to a different file descriptor number
    newstdout = os.dup(1)

    # /dev/null is used just to discard what is being printed
    devnull = os.open('/dev/null', os.O_WRONLY)

    # Duplicate the file descriptor for /dev/null
    # and overwrite the value for stdout (file descriptor 1)
    os.dup2(devnull, 1)

    # Close devnull after duplication (no longer needed)
    os.close(devnull)

    # Use the original stdout to still be able
    # to print to stdout within python
    sys.stdout = os.fdopen(newstdout, 'w')

One important thing to note is that a process gets three different file descriptors from the OS when launched:

  • stdin: 0
  • stdout: 1
  • stderr: 2

As explained in the comments, the code above takes advantage of the file descriptor for stdout and the file descriptor duplication functions to make trick the C code into using a different stdout while still keeping a reference to the original stdout in the python code to be able to print.

/dev/null is a special device file (everything in UNIX is a file!) that swallows everything written to it like a black hole. dup duplicates a file descriptor. If you are used to Windows, a file descriptor in UNIX is a special integer which represents an open file, it's like a Windows file handle.

The program is opening /dev/null for writing (only), taking a copy of it's file descriptor, closing the open file (because having a file descriptor is enough for UNIX to write to a file, you don't need to keep the resources open), then assigning the open file to sys.stdout.

Remember sys is the Python module which represents all sorts of system-specific resources, such as the file system. So, in UNIX sys.stdout will represent /dev/stdout i.e. the system STDOUT stream.

So, altogether, this code is fooling Python into thinking that /dev/null/ is STDOUT so now every time your program writes to STDOUT with, say, the print statement (function in Python3) then it will really be writing to /dev/null and you will never see the resulting text on your console.

See manual pages for the C runtime functions that underlie these Python functions.

Basically, they duplicate a file descriptor, into either a new file descriptor (with dup()) or into a file descriptor specified in the call, with dup2().

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!