Runs is a Python library (version 1.3.0) that enhances the standard `subprocess` module by providing improved functions to execute blocks of text as sequences of shell commands. It adds features like multi-command execution, line continuations, comment handling, optional logging, error handling, lazy evaluation, and defaults to UTF-8 encoding. It offers more robust handling for scenarios that often trip up the native `subprocess` functions.
pip install runsVerified import paths — ran on the pinned version, not inferred.
This example demonstrates how to use `runs.run()` to execute a multi-line block of commands and capture their output. It also shows how to enable echoing commands and handle exceptions from failing subprocesses. The library provides a more convenient interface for common shell interactions than the raw `subprocess` module.
Use explicit line continuations for multi-line shell commands within a single text block, or pass commands as a list of strings if precise command separation is critical, e.g., `runs.run(['command arg1 arg2', 'another_command'])`.
Avoid constructing command strings with unsanitized user input. If user input must be part of a command, pass the command and its arguments as a list of strings (where each element is an argument) rather than a single string, to bypass shell interpretation. Alternatively, use `shlex.quote()` to properly escape individual arguments.
For asynchronous or parallel execution, consider directly using `subprocess.Popen` or dedicated async/parallel processing libraries like `asyncio.create_subprocess_exec` or `multiprocessing`.
Adjust your code to iterate over the returned list if you expect multiple outputs, or access `result[0]` if only the first command's output is relevant. Remember that each element in the list is the `stdout` of a command, not a `CompletedProcess` object.
Install the library using pip: `pip install runs`
Pass the command as a single string: `runs.execute("ls -l")`Verify that the shell command is correct, exists in the system's PATH, and has the necessary permissions. You can also disable checking with `check=False` if a non-zero exit status is expected for your use case.
Iterate over the generator to access the results: `for result in runs.lazy_execute("echo hello"): print(result.stdout)`No dependency data recorded yet.