Skip to main content

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 arguments
  • stdin: 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 directory
  • env: Environment variables dict
  • check: Raise exception on unacceptable exit (default: True)
  • ok_exitcodes: Acceptable exit codes (default: 0, use ANY_EXITCODE for any) - can be int or container
  • text: Text mode for I/O (default: True)
  • **kwargs: Additional subprocess arguments

Methods

  • execute() -> Process: Execute the process and wait for completion
  • wait() -> int: Wait for process completion and return exit code
  • kill(signal=15) -> None: Send signal to process
  • pid -> int | None: Get process ID
  • stdout -> str: Get captured stdout
  • stderr -> str: Get captured stderr
  • returncode -> 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/null redirection
  • STDOUT: stdout redirection marker
  • STDERR: 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)

Source distribution for shello 0.2.0
File Size Uploaded Provenance
shello-0.2.0.tar.gz 21.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for shello 0.2.0
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page