From ee7b3798221afeaf4ccfb1e3d6d6b8b805fd0f97 Mon Sep 17 00:00:00 2001 From: "pavel.muhortov" Date: Wed, 16 Jun 2021 20:20:35 +0300 Subject: [PATCH] add srchproc.py --- README.md | 35 +++++++++++++++- srchproc.py | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 srchproc.py diff --git a/README.md b/README.md index c197d65..336a45e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # utils * [sendmail.py](https://git.hmp.today/pavel.muhortov/utils#sendmail-py) +* [srchproc.py](https://git.hmp.today/pavel.muhortov/utils#srchproc-py) ____ ## sendmail.py | PARAMETERS | DESCRIPTION | DEFAULT| @@ -17,7 +18,8 @@ ____ |**[--text]**|mail body text|'no text'| |**[--type]**|mail body type: plain, html|plain| |**[--file]**|mail attachment files|`None`| -Example usage in terminal with Python: + +Example usage in terminal with Python: ```shell python3 ./sendmail.py -u user@gmail.com -p pass -d addr1@gmail.com,addr2@gmail.com ``` @@ -33,4 +35,33 @@ from sendmail import Mail msg = Mail(smtp_user='user@gmail.com', smtp_pass='pass', mail_dest='addr1@gmail.com,addr2@gmail.com') log = msg.send() print(log) -``` \ No newline at end of file +``` +____ +## srchproc.py +| PARAMETERS | DESCRIPTION | DEFAULT| +|-------------|-------------|--------| +|**[-h]**|print help and exit|| +|**[--find]**|find process pid, name or arguments|| +|**[--exclude]**|exclude process pid, name or arguments|`None`| +|**[--self]**|find a clones of self|`True`| + +Example usage in terminal with Python for find all running processes: +```shell +python3 ./srchproc.py +``` +Example usage in terminal with make the script executable for find all specified processes: +```shell +chmod u+x ./sendmail.py +./srchproc.py --find ssh --exclude sftp +``` +Example usage in Python for find a clones of self: +```Python +from os import getpid +from sys import argv +from srchproc import Proc + +processes = Proc.search(' '.join(argv), str(getpid())) +if processes: + for process in Proc.list(): + print(process) +``` diff --git a/srchproc.py b/srchproc.py new file mode 100644 index 0000000..ce6c220 --- /dev/null +++ b/srchproc.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + + +from os import path, getpid +from subprocess import Popen, PIPE +from sys import argv, platform + + +class Proc: + """ + Find a running process from Python + """ + @staticmethod + def list_windows(): + """ + Find all running process with wmi + :return: list of dictionaries with descriptions of found processes + """ + execlist = [] + separate = b'\r\r\n' + out, err = Popen(['wmic', 'process', 'get', 'CommandLine,ExecutablePath,Name,ProcessId', '/format:list'], + stdout=PIPE, stderr=PIPE).communicate() + for line in out.split(separate + separate): + execpid, exename, exepath, cmdline = None, None, None, None + for subline in line.split(separate): + if b'ProcessId=' in subline: + execpid = subline.split(b'=')[1].decode('utf-8') + if b'Name=' in subline: + exename = subline.split(b'=')[1].decode('utf-8') + if b'ExecutablePath=' in subline: + exepath = subline.split(b'=')[1].decode('utf-8') + if b'CommandLine=' in subline: + cmdline = subline.split(b'=')[1].decode('utf-8') + if execpid and exename: + execlist.append({'execpid': execpid, 'exename': exename, 'exepath': exepath, 'cmdline': cmdline}) + return execlist + + @staticmethod + def list_linux(): + """ + Find all running process with ps + :return: list of dictionaries with descriptions of found processes + """ + execlist = [] + out, err = Popen(['/bin/ps', '-eo', 'pid,args'], stdout=PIPE, stderr=PIPE).communicate() + for line in out.splitlines(): + execpid = line.split(b' ')[0].decode('utf-8') + exepath = line.split(b' ')[1].decode('utf-8') + exename = path.basename(exepath) + cmdline = line.split(b' ', 1)[1].decode('utf-8') + if execpid and exename: + execlist.append({'execpid': execpid, 'exename': exename, 'exepath': exepath, 'cmdline': cmdline}) + return execlist + + @staticmethod + def list(): + """ + Find all running process + :return: list of dictionaries with descriptions of found processes + """ + if platform.startswith('linux'): + return Proc.list_linux() + elif platform.startswith('win32'): + return Proc.list_windows() + elif platform.startswith('darwin'): + return Proc.list_linux() + else: + return None + + @staticmethod + def search(find: str, exclude: str = None): + """ + Find specified processes + :param find: find process pid, name or arguments + :param exclude: exclude process pid, name or arguments + :return: list of dictionaries with descriptions of found processes + """ + proc_found = [] + for proc in Proc.list(): + if exclude and (exclude in proc['execpid'] or exclude in proc['exename'] or + exclude in proc['exepath'] or exclude in proc['cmdline']): + pass + elif find in proc['execpid'] or find in proc['exename'] or \ + find in proc['exepath'] or find in proc['cmdline']: + proc_found.append(proc) + if len(proc_found) == 0: + return None + else: + return proc_found + + +if __name__ == "__main__": + from argparse import ArgumentParser + + args = ArgumentParser( + prog='Proc', + description='Find a running process from Python', + epilog='Dependencies: Python 3 (tested version 3.9.5)' + ) + args.add_argument('--find', type=str, required=False, + help='find process pid, name or arguments') + args.add_argument('--exclude', type=str, default=None, required=False, + help='exclude process pid, name or arguments') + args.add_argument('--self', action='store_true', required=False, + help='find a clones of self') + args = vars(args.parse_args()) + if args['find']: + processes = Proc.search(args['find'], args['exclude']) + elif args['self']: + processes = Proc.search(' '.join(argv), str(getpid())) + else: + processes = Proc.list() + if processes: + for process in processes: + print(process)