try_run.py 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. # -*- coding:utf-8 -*-
  2. """
  3. Utility: Safe command execution wrapper used across the project.
  4. Provides a single try_run function with consistent behavior.
  5. """
  6. import subprocess
  7. import sys
  8. def try_run(command, logger=None, **kwargs):
  9. # type: (list, object, **object) -> str | None
  10. """Safely run a subprocess command and return decoded output or None on failure.
  11. Args:
  12. command (list): Command array to execute
  13. logger (object, optional): Logger instance for debug output
  14. **kwargs: Additional arguments passed to subprocess.check_output
  15. Returns:
  16. str or None: Command output as string, or None if command failed
  17. - Adds a default timeout=60s on Python 3 to avoid hangs
  18. - Decodes output as text via universal_newlines=True
  19. - Logs at debug level when logger is provided
  20. """
  21. try:
  22. if sys.version_info[0] >= 3 and "timeout" not in kwargs:
  23. kwargs["timeout"] = 60
  24. return subprocess.check_output(command, universal_newlines=True, **kwargs) # type: ignore
  25. except Exception as e: # noqa: BLE001 - broad for subprocess safety
  26. if logger is not None:
  27. try:
  28. logger.debug("Command failed: %s", e) # type: ignore
  29. except Exception:
  30. pass
  31. return None