|
16 | 16 |
|
17 | 17 | def run_shell_cmd( |
18 | 18 | cmd: str | list[str], |
| 19 | + callback: Callable[[Popen], None] | None = None, |
19 | 20 | cwd: Path | str | None = None, |
20 | 21 | env: dict[str, str] | None = None, |
21 | | - start_new_session: bool = False, |
22 | | - callback: Callable[[Popen], None] | None = None, |
23 | 22 | executable: str | None = None, |
24 | 23 | log_output: bool = False, |
25 | 24 | quiet: bool = False, |
| 25 | + start_new_session: bool = False, |
26 | 26 | taskname: str | None = None, |
27 | 27 | ) -> tuple[bool, str]: |
28 | 28 | """ |
29 | 29 | Run a command in a shell. |
30 | 30 |
|
31 | 31 | :param cmd: The command to run. |
32 | | - :param cwd: Change to this directory before running cmd. |
33 | | - :param env: Environment variables to set before running cmd. |
| 32 | + :param callback: Called with the ``Popen`` process object. |
| 33 | + :param cwd: Change to this directory before running the command. |
| 34 | + :param env: Environment variables to set before running the command. |
| 35 | + :param executable: Interpreter to run command in (e.g. "/bin/bash"). |
| 36 | + :param log_output: Log output from successful command? (Error output is always logged.) |
| 37 | + :param quiet: Log ``INFO`` messages as ``DEBUG``. |
34 | 38 | :param start_new_session: Run process in a new session? |
35 | | - :param callback: Optional callable, called with the Popen process object. |
36 | | - :param executable: Interpreter to use (e.g. "/bin/bash") |
37 | | - :param log_output: Log output from successful cmd? (Error output is always logged.) |
38 | | - :param quiet: Log INFO messages as DEBUG. |
39 | 39 | :param taskname: Name of task executing this command, for logging. |
40 | | - :return: A result object providing combined stder/stdout output and success values. |
| 40 | + :return: Success indication and combined ``stdout`` / ``stderr``. |
| 41 | +
|
| 42 | + The ``Callable`` specified by the ``callback`` argument will be called once with the ``Popen`` |
| 43 | + object as soon as it is available; i.e. it may be called while the command is running, and does |
| 44 | + not wait for the command to complete. |
| 45 | +
|
| 46 | + Use ``executable`` to use a shell other than the ``subprocess.Popen`` default, ``/bin/sh``. |
| 47 | +
|
| 48 | + It is assumed that ``uwtools.api.loggin.use_uwtools_logger`` has previously been called to set |
| 49 | + up logging if ``log_output`` is ``True``. |
| 50 | +
|
| 51 | + The ``start_new_session`` argument is connected directly to the argument of the same name when |
| 52 | + ``subprocess.Popen`` is called. Among other potential use cases, it prevents the command from |
| 53 | + receiving a ``SIGINT`` generated by a user Ctrl-C, useful when the command is running in a |
| 54 | + thread and the main control thread should handle the interrupt. |
| 55 | +
|
| 56 | + If ``taskname`` is provided, log messages will be prefixed with ``[<taskname>]``. |
41 | 57 | """ |
42 | 58 | pre = f"[{taskname}] " if taskname else "" |
43 | 59 | logfunc = log.debug if quiet else log.info |
|
0 commit comments