General
The core of comrun is a CommandRunner class. It's how you run commands and get results. This section covers the basics of using it.
Running a command
Just create a CommandRunner instance and call it with the command you want to run:
from comrun import CommandRunner
runner = CommandRunner()
runner.run('echo "The cake is a lie."') # (1)!
- Prints to stdout:
You can also run commands asynchronously:
- Prints to stdout:
The same runner instance can be reused indefinitely to call other commands. This allows you to invoke multiple commands using the same base configuration, and override individual options on each run as needed (more on this in Configuration section).
Extra CommandRunner trivia
CommandRunnerinstances are callable:__call__forwards to.run(). So you can dorunner("ls -la")instead ofrunner.run("ls -la"), for example.- Runner accepts commands both as a string (
"git status") and as an argv (["git", "status"]). Strings are split withshlex.split()internally.
Reading results
Each run returns a CommandResult instance with details about the execution:
resultis aCommandResultinstance with details about this run.
Exit status
There are several ways to check how the command exited:
- Raw exit code (0 means success).
Truewhenexit_code == 0.Truewhenexit_code != 0.
CommandResult instance is truthy upon success, so you can use it in conditionals:
Captured output
Output of the command is captured in CommandOutput objects. Result has three properties of this type:
- Stdout output.
- Stderr output.
- Output of stdout + stderr in chronological order.
CommandOutput objects allow you to access their content in several ways:
-
lines: A tuple of output lines, each without trailing whitespaces/newlines.If you want to process lines right as they come, look into live output hooks.
-
text: Full output as a single string. -
stripped: Full output as a single string, but without leading and trailing whitespaces/newlines. value: Same asstripped, but isNoneif the output is empty.
These options keep command-output handling short and readable.
Configuration
The strength of comrun is in the ability to create pre-configured runners. There are 3 ways to configure a CommandRunner:
-
Via constructor arguments:
- This runner will be silent and will raise exceptions on failures.
-
By modifying an existing runner via
.with_options():- This runner will now print its output (
quiet=False), but keepscheck=Truefrombase_runner.
.with_options()always creates a newCommandRunnerinstance, so the original remains unchanged. - This runner will now print its output (
-
By passing options to individual
.run()calls:-
This specific run will not raise on failure (
check=False), even thoughloud_runnerhascheck=True.It still prints output like
loud_runneris configured to do.
This, of course, works the same with async calls via
.run_async(). -
These methods can be combined as needed to create runners that fit your use case, all while minimizing repeated boilerplate when calling commands.
Available configuration options are listed below.
Working directory (cwd)
Working directory for the command is set with cwd:
- Commands run via this runner will execute with
/path/to/diras their working directory.
Environment variables (env)
You can override environment variables for the command with env:
- Commands run via this runner will have
MY_VARset to"value"in their environment.
Environment variables set via env replace the entire environment for the command.
To add variables while keeping existing ones, merge with os.environ:
Silencing output (quiet)
By default, comrun prints the command's output to the console as it appears. You can disable this behavior by passing quiet=True:
- Prints
Potato.to the console. - Prints nothing, no matter how loud the command is.
POTATO!is still captured and available inresult.stdout.
Raising on failures (check)
By default, comrun will quietly execute the command even if it fails and returns a non-zero exit code. If you want to catch it as an exception instead, you can pass check=True:
result = runner("exit 1") # (1)!
try:
runner("exit 1", check=True) # (2)!
except CommandError as exc:
print(exc)
- Non-zero exits set
result.failureto True. - With
check=True, non-zero exits raiseCommandError.
Read more about CommandError in the Reference section.
Using WSL on Windows (wsl)
On Windows, comrun can automatically prefix commands with wsl for you to run them inside the Windows Subsystem for Linux. This behavior is controlled with the wsl option (default: True on Windows, ignored on POSIX):
- Commands run via this runner will execute with the native Windows shell instead of WSL (when on Windows).
Encoding (encoding)
By default, comrun decodes command output using the system's preferred encoding. You can override this with the encoding option:
- Commands run via this runner will decode output using UTF-8.
Others
You can find more configuration options in the Advanced usage and Reference sections.