suppress scapy warning message when importing the

2020-07-02 22:46发布

问题:

I'm writing a small script, that gathers some information using scapy and then returns some xml code, that I'll pass on to the xmlrpc interface of metasploit. I'd like it that my script only returns xml, and no additional warnings etc.

I can suppress most scapy output, with adding the option verbose=0 to my sr1 command. What I still get before every output, and I assume it returns this warning when I'm loading the module, is:

WARNING: No route found for IPv6 destination :: (no default route?)

I can easily redirect that output, by calling my script like this:

 ./myscript 2> /dev/null

but I'd like to incorporate this into the script. For that I've found a hint, that one could have a NullDevice class, that doesn't write anything, and then set sys.stderr to an instantiation of that NullDevice class.

This only works unfortunately after I've already loaded the module, so I still have the Warning, and it only redirects any following messages sent to stderr.

How can I suppress that warning message to appear on my screen?

回答1:

You can get rid of warnings by scapy by adding:

logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

before importing Scapy. This will suppress all messages that have a lower level of seriousness than error messages.


for example:

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
...


回答2:

I think this is the correct way.

>>> import sys
>>> sys.stderr = None            # suppress stderr
>>> from scapy.all import *
>>> sys.stderr = sys.__stderr__  # restore stderr
>>> print("other errors can be shown", file=sys.stderr)
other errors can be shown
>>> 


回答3:

I think perhaps the python3 version of scapy prints a message from a different logger or at a high level. Here's some code I've used to suppress output on module import.

from contextlib import contextmanager

# It looks like redirect_stderr will be part of Python 3.5 as follows:
# from contextlib import redirect_stderr
# Perhaps if you're looking at this code and 3.5 is out, this function could be
# removed.
@contextmanager
def redirect_stderr(new_target):
    """
    A context manager to temporarily redirect stderr. Example use:
    with open(os.devnull, 'w') as f:
        with redirect_stderr(f):
            # stderr redirected to os.devnull. No annoying import messages
            # printed on module import
            from scapy.all import *
    # stderr restored
    """
    import sys
    old_target, sys.stderr = sys.stderr, new_target # replace sys.stdout
    try:
        yield new_target # run some code with the replaced stdout
    finally:
        sys.stderr = old_target # restore to the previous value


# Don't print the annoying warning message that occurs on import
with open(os.devnull, 'w') as errf:
    with redirect_stderr(errf):
        from scapy.all import sr, ICMP, IP, traceroute


回答4:

With Python3, redefining sys.stderr to None threw an exception AttributeError: 'NoneType' object has no attribute 'write'. Instead, defining it to os.devnull does the job:

import os
import sys
sys.stderr = os.devnull # suppress stderr
from scapy.all import *
sys.stderr = sys.__stderr__ # restore stderr