simple cross-platform wrapper for lsof/netstat to tell what processes are listening for network connections
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import platform | |
import subprocess | |
import sys | |
def eprint(*args, **kwargs): | |
print(*args, file=sys.stderr, **kwargs) | |
def str2bool(v): | |
if v.lower() in ('yes', 'true', 't', 'y', '1'): | |
return True | |
elif v.lower() in ('no', 'false', 'f', 'n', '0'): | |
return False | |
else: | |
raise argparse.ArgumentTypeError('Boolean value expected.') | |
def cmd_macos(port=None, transport=None, ipv=None): | |
return "lsof -nP -i{ipv:s}{transport:s}{port:s}".format( | |
ipv="{:d}".format(ipv) if ipv else "", | |
transport=transport.upper() if transport else "", | |
port=":{:d}".format(port) if port else "" | |
) | |
def cmd_linux(port=None, transport=None, ipv=None): | |
if ipv == 4: | |
ipv_part = " | grep --color=never -v -e \"tcp6\" -e \"udp6\"" | |
elif ipv == 6: | |
ipv_part = " | grep --color=never -e \"tcp6\" -e \"udp6\"" | |
else: | |
ipv_part = "" | |
return "netstat -lnp{transport:s}".format( | |
ipv=ipv_part, | |
transport=transport[0].lower() if transport else "tu", | |
port=" | grep --color=never \":{:d}\"".format(port) if port else "" | |
) | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description='List processes listening for network connections. (Wraps lsof on macOS; netstat on Linux.)') | |
parser.add_argument('-p', '--port', type=int, default=None, help='Filter to processes listening on the given port. Default: none (all).') | |
parser.add_argument('-t', '--transport', type=str, default=None, choices=['tcp','udp'], help='Specifies TCP or UDP. Default: none (both).') | |
parser.add_argument('-i', '--ip', type=int, default=None, choices=[4, 6], help='Specifies IPv4 or IPv6. Default: none (both).') | |
parser.add_argument('-d', '--debug', type=str2bool, default='false', help='Whether to print the lsof/netstat command to be executed to stderr. Default: False.') | |
args = parser.parse_args() | |
if "darwin" in platform.system().lower(): | |
cmd = cmd_macos( | |
port=args.port, | |
transport=args.transport, | |
ipv=args.ip | |
) | |
elif "linux" in platform.system().lower(): | |
cmd = cmd_linux( | |
port=args.port, | |
transport=args.transport, | |
ipv=args.ip | |
) | |
else: | |
eprint("Platform {:s} is unsupported.".format(platform.system())) | |
sys.exit(1) | |
if args.debug: | |
eprint("+ {:s}".format(cmd)) | |
eprint("") | |
p = subprocess.Popen(cmd, shell=True, stdout=sys.stdout, stderr=sys.stderr) | |
sys.exit(p.wait()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Installation