1. import psutil
  2. import argparse
  3. import os
  4. import signal
  5. import sys
  6. import time
  7. def get_processes_by_file(filepath):
  8. """Returns a list of processes accessing the given file."""
  9. processes = []
  10. for proc in psutil.process_iter(['pid', 'name', 'open_files']):
  11. try:
  12. for open_file in proc.info['open_files']:
  13. if open_file.path == filepath:
  14. processes.append(proc)
  15. break # Avoid duplicates if file is opened multiple times by the same process
  16. except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
  17. pass
  18. return processes
  19. def terminate_processes(processes, force=False):
  20. """Terminates the given processes."""
  21. for proc in processes:
  22. try:
  23. print(f"Terminating process {proc.info['name']} (PID: {proc.pid})...")
  24. if force:
  25. proc.kill() # Force kill
  26. else:
  27. proc.terminate() # Terminate gracefully
  28. # Wait for process to terminate
  29. proc.wait(timeout=5) #wait 5 seconds for process to terminate
  30. if proc.is_running():
  31. print(f"Process {proc.info['name']} (PID: {proc.pid}) did not terminate gracefully. Attempting kill.")
  32. proc.kill()
  33. except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
  34. print(f"Process {proc.info['name']} (PID: {proc.pid}) already terminated or does not exist.")
  35. except Exception as e:
  36. print(f"Error terminating process {proc.info['name']} (PID: {proc.pid}): {e}")
  37. def monitor_file(filepath, interval=5):
  38. """Monitors a file for processes accessing it."""
  39. print(f"Monitoring file: {filepath} (checking every {interval} seconds). Press Ctrl+C to stop.")
  40. try:
  41. while True:
  42. processes = get_processes_by_file(filepath)
  43. if processes:
  44. print(f"Processes accessing {filepath}:")
  45. for proc in processes:
  46. print(f" - {proc.info['name']} (PID: {proc.pid})")
  47. else:
  48. print(f"No processes currently accessing {filepath}.")
  49. time.sleep(interval)
  50. except KeyboardInterrupt:
  51. print("\nMonitoring stopped.")
  52. def main():
  53. parser = argparse.ArgumentParser(description="Teardown processes accessing a binary file.")
  54. parser.add_argument("filepath", help="Path to the binary file to monitor.")
  55. parser.add_argument("-t", "--terminate", action="store_true", help="Forcefully terminate processes accessing the file.")
  56. parser.add_argument("-i", "--interval", type=int, default=5, help="Monitoring interval in seconds (default: 5).")
  57. args = parser.parse_args()
  58. if not os.path.exists(args.filepath):
  59. print(f"Error: File not found: {args.filepath}")
  60. sys.exit(1)
  61. if args.terminate:
  62. processes = get_processes_by_file(args.filepath)
  63. terminate_processes(processes, force=True)
  64. else:
  65. monitor_file(args.filepath, args.interval)
  66. if __name__ == "__main__":
  67. main()

Add your comment