Shello
A modern Python library for shell-style process execution with elegant syntax and powerful features.
Features
- Shell-like syntax:
shell.echo("hello")instead of complex subprocess calls - Pipeline support:
shell.echo("hello") | shell.wc("-w")for Unix-style pipes - I/O redirection: Support for stdin/stdout/stderr redirection with
DEVNULL,STDOUT,STDERR - Modern Python: Built with Python 3.10+ features and type hints
- Comprehensive error handling: Clear exceptions with detailed error information
- Flexible configuration: Environment variables, working directory, and more
Quick Start
from shello import shell
# Basic command execution
result = shell.echo("Hello, World!").execute()
print(result.stdout) # "Hello, World!\n"
# Command with arguments
result = shell.ls("-la", "/tmp").execute()
# Pipelines
result = (shell.echo("one two three") | shell.wc("-w")).execute()
print(result.stdout) # "3\n"
# With stdin
result = shell.wc("-c", stdin="Hello World").execute()
print(result.stdout) # "11\n"
# Environment variables
result = shell.env("CUSTOM_VAR=value").execute()
# I/O redirection
result = shell.echo("error", stderr=STDOUT).execute() # stderr to stdout
result = shell.echo("data", stdout=DEVNULL).execute() # discard output
# Acceptable exit codes
result = shell.command_that_might_fail(ok_exitcodes=(0, 1)).execute() # accept 0 or 1
result = shell.any_command(ok_exitcodes=ANY_EXITCODE).execute() # accept any exit code
Installation
pip install shello
# or with uv
uv add shello
API Reference
Shell Class
The main factory class for creating Process objects.
from shello import Shell
# Create shell with default options
shell = Shell(check=False, cwd="/tmp")
# Create processes
process1 = shell("echo", "hello")
process2 = shell.echo("hello") # Attribute access (underscores -> hyphens)
Process Class
Represents a process that can be executed.
Constructor
Process(program, *args,
stdin=DEVNULL, stdout=None, stderr=None,
cwd=None, env=None, check=True, ok_exitcodes=0, text=True, **kwargs)
Parameters:
program: Command to execute*args: Command line argumentsstdin: Input source (DEVNULL, string, bytes, file-like object)stdout: Output destination (None,DEVNULL,STDOUT,STDERR, file path, file object)stderr: Error output destination (same options as stdout)cwd: Working directoryenv: Environment variables dictcheck: Raise exception on unacceptable exit (default:True)ok_exitcodes: Acceptable exit codes (default:0, useANY_EXITCODEfor any) - can be int or containertext: Text mode for I/O (default:True)**kwargs: Additional subprocess arguments
Methods
execute() -> Process: Execute the process and wait for completionwait() -> int: Wait for process completion and return exit codekill(signal=15) -> None: Send signal to processpid -> int | None: Get process IDstdout -> str: Get captured stdoutstderr -> str: Get captured stderrreturncode -> int: Get process return code
Pipeline Operator
# Unix-style pipelines
result = (shell.echo("hello") | shell.wc("-c")).execute()
# Multi-step pipelines
result = (shell.cat("file.txt") | shell.grep("pattern") | shell.wc("-l")).execute()
Constants
ANY_EXITCODE: Accepts any valid exit code (0-255)DEVNULL:/dev/nullredirectionSTDOUT: stdout redirection markerSTDERR: stderr redirection marker
Exception Hierarchy
ShellError # Base exception
├── ProcessError # Process execution failures
├── InvalidArgument # Invalid arguments
└── InvalidOperation # Invalid operations
Examples
Environment Variables
env = {"PATH": "/usr/bin:/bin", "DEBUG": "1"}
result = shell.python("script.py", env=env).execute()
Working Directory
result = shell.ls("-la", cwd="/home/user").execute()
Error Handling
try:
shell.nonexistent_command().execute()
except ProcessError as e:
print(f"Command failed: {e.exit_code}")
print(f"Output: {e.stdout}")
I/O Redirection
# Capture stderr
result = shell.command("2>&1", stderr=STDOUT).execute()
# Discard output
result = shell.verbose_command(stdout=DEVNULL).execute()
# Output to file
result = shell.echo("data", stdout="output.txt").execute()
Background Processing
# Execute without waiting
process = shell.long_running_command(wait=False)
# Later...
process.wait() # Wait for completion
Development
# Clone repository
git clone https://github.com/kszakharov/shello
cd shello
# Install dependencies
uv sync
# Run tests
uv run pytest
# Run demo
uv run python demo.py
License
MIT License - see LICENSE file for details.
Metadata
Release files for shello 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| shello-0.2.0.tar.gz | 21.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shello-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 37.2 kB
Release files / shello-0.2.0.tar.gz
| Download URL | shello-0.2.0.tar.gz |
|---|---|
| Size | 21.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e11f130f283ed85d05c37985dc1d60e7038a8a6a6610c7a450992af542c22f29
|
|
BLAKE2b-256 checksum How to use checksums |
d6e371b002e1c170cbf56c88720fba0c9145bd31c1843439310b9358180f7fbe
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / shello-0.2.0-py3-none-any.whl
| Download URL | shello-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4123664d72c376575226641faabaf2007196fae55ee1dcaa1b25aa6d98593f5a
|
|
BLAKE2b-256 checksum How to use checksums |
5b07880d62f341d0fcd3b5615f63bd26712abc1971a12c92338d5f38ba96f78d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.10.9 {"installer":{"name":"uv","version":"0.10.9","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for shello 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.