Skip to main content

A modern Python library for shell-style process execution

Project description

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.11+ 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_data)  # "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_data)  # "3\n"

# With stdin
result = shell.wc("-c", stdin="Hello World").execute()
print(result.stdout_data)  # "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_data -> str: Get captured stdout
  • stderr_data -> 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shello-0.1.0.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shello-0.1.0-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file shello-0.1.0.tar.gz.

File metadata

  • Download URL: shello-0.1.0.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for shello-0.1.0.tar.gz
Algorithm Hash digest
SHA256 da13908fe14f7458b5dbdbe2a74d7332fe33615311db4462bfacce36909a19b9
MD5 9c6933ab27fb8fbf410806488041f69b
BLAKE2b-256 7410d130007a68eb9f895a2f0c047fd6c1417ecaa8b8a640fd332d7b9130ede0

See more details on using hashes here.

File details

Details for the file shello-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: shello-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for shello-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fb60c0d362cf5466a5877967cf9a354b4fa736bf3d12685e00eea179d13f4233
MD5 204a4a0f4b9ab4c30065092c73b98be3
BLAKE2b-256 414eb4dfc832fbee585e769b79d62cccf3e2e1c67c37cc9f9406d31de83788c7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page