or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

command-execution.mdcontrib.mderror-handling.mdindex.mdio-handling.mdprocess-management.mdutilities.md
tile.json

tessl/pypi-sh

Python subprocess replacement that allows calling system commands as Python functions

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/sh@2.2.x

To install, run

npx @tessl/cli install tessl/pypi-sh@2.2.0

index.mddocs/

sh

A comprehensive Python subprocess replacement that allows calling any system command as if it were a Python function. The sh library provides a more Pythonic interface to shell commands with advanced process management, piping, background execution, and real-time output streaming for Unix-like systems.

Package Information

  • Package Name: sh
  • Language: Python
  • Installation: pip install sh
  • Supported Platforms: Linux, macOS, BSD (Unix-like systems only)
  • Python Versions: 3.8-3.12, PyPy

Core Imports

import sh

For specific commands:

from sh import ls, git, docker  # Any system command

For classes and utilities:

from sh import Command, pushd, glob, ErrorReturnCode

For contrib commands:

from sh.contrib import git, sudo, bash  # Enhanced command versions

Basic Usage

import sh

# Call any system command as a Python function
output = sh.ls("-la", "/tmp")
print(output)

# Chain commands with pipes
result = sh.grep(sh.ps("aux"), "python")

# Run commands in the background
proc = sh.sleep(10, _bg=True)
print("Command running in background...")
proc.wait()

# Handle command output in real-time
def process_line(line):
    print(f"Output: {line.strip()}")

sh.tail("-f", "/var/log/system.log", _out=process_line)

# Change directory temporarily
with sh.pushd("/tmp"):
    files = sh.ls()  # lists files in /tmp
    print(files)
# Back to original directory

# Handle errors
try:
    sh.ls("/nonexistent")
except sh.ErrorReturnCode_2 as e:
    print(f"Command failed: {e}")

Architecture

The sh library uses a dynamic command resolution system built around these core components:

  • Command: Represents an un-run system program that can be configured and executed
  • RunningCommand: Manages executing processes with advanced I/O handling and control
  • Dynamic Resolution: Any attribute access (like sh.ls) creates Command objects for system programs
  • Exception Hierarchy: Specific exception classes for different exit codes and signals
  • Process Management: Background execution, real-time streaming, piping, and signal handling

This design enables treating shell commands as first-class Python objects while maintaining full control over process execution, I/O redirection, and error handling.

Capabilities

Command Execution

Core functionality for executing system commands with comprehensive process control, argument handling, and execution modes including foreground, background, and interactive execution.

def __call__(*args, **kwargs): ...  # Command execution
def bake(*args, **kwargs): ...      # Pre-configure command arguments

Command Execution

Process Management

Advanced process control including background execution, process monitoring, signal handling, and process lifecycle management with support for long-running commands.

def wait(): ...                     # Wait for background process completion
def kill(): ...                     # Terminate running process
def terminate(): ...                # Gracefully terminate process
def is_alive(): ...                 # Check if process is running

Process Management

Input/Output Handling

Comprehensive I/O redirection and streaming capabilities including real-time output processing, piping between commands, input feeding, and output capturing with multiple formats.

def _out(callback): ...             # Real-time output processing  
def _err(callback): ...             # Real-time error processing
def _in(data): ...                  # Feed input to command
def _piped: ...                     # Enable piping to other commands

Input/Output Handling

Error Handling

Robust error handling system with specific exception classes for different failure modes, exit code management, and comprehensive error information capture.

class ErrorReturnCode(Exception): ...
class ErrorReturnCode_1(ErrorReturnCode): ...  # Exit code 1
class SignalException(Exception): ...
class TimeoutException(Exception): ...
class CommandNotFound(Exception): ...

Error Handling

Contrib Commands

Enhanced command wrappers that provide optimized defaults and specialized functionality for common tools like git, sudo, bash, and ssh.

@contrib("git")
def git(orig): ...                  # Git with optimized defaults
@contrib("sudo") 
def sudo(orig): ...                 # Sudo with password handling
@contrib("bash")
def bash(orig): ...                 # Bash with -c flag pre-configured

Contrib Commands

Utilities and Helpers

Additional utilities including directory manipulation, enhanced globbing, logging, and command introspection tools for advanced shell integration scenarios.

def pushd(path): ...                # Directory context manager
def glob(pattern): ...              # Enhanced glob with sh integration  
class Logger: ...                   # Command execution logger

Utilities

Types

class Command:
    """Represents an un-run system program."""
    def __init__(self, path: str, search_paths=None): ...
    def __call__(self, *args, **kwargs): ...  # Returns str or RunningCommand
    def bake(self, *args, **kwargs): ...      # Returns new Command
    def __str__(self) -> str: ...             # String representation with path
    def __repr__(self) -> str: ...            # Formal string representation
    def __eq__(self, other) -> bool: ...      # Equality comparison

class RunningCommand:
    """Represents an executing command process."""
    def wait(self): ...
    def kill(self): ...
    def terminate(self): ...
    def signal(self, sig): ...                    # Send signal to process
    def is_alive(self) -> bool: ...
    @property
    def pid(self) -> int: ...                     # Process ID
    @property
    def stdout(self) -> str: ...
    @property  
    def stderr(self) -> str: ...
    @property
    def exit_code(self) -> int: ...
    @property
    def process(self): ...                        # Access to subprocess.Popen object

class ErrorReturnCode(Exception):
    """Base exception for command execution errors."""
    def __init__(self, full_cmd: str, stdout: bytes, stderr: bytes): ...
    @property
    def exit_code(self) -> int: ...
    @property
    def full_cmd(self) -> str: ...                # Complete command executed
    @property
    def stdout(self) -> bytes: ...                # Command stdout output  
    @property
    def stderr(self) -> bytes: ...                # Command stderr output

class SignalException(Exception):
    """Exception raised when process is terminated by a signal."""
    def __init__(self, full_cmd: str, signal_code: int): ...

class TimeoutException(Exception):
    """Exception raised when command times out."""
    def __init__(self, full_cmd: str, timeout: float): ...

class CommandNotFound(Exception):
    """Exception raised when command cannot be found in PATH."""
    def __init__(self, command: str): ...

class ForkException(Exception):
    """Exception raised when there's an error in the fork process."""
    def __init__(self, command: str, error: str): ...

class Logger:
    """Memory-efficient command execution logger."""
    def __init__(self, name: str, context: dict = None): ...
    def log(self, level: str, message: str): ...
    def info(self, message: str): ...
    def debug(self, message: str): ...
    def warning(self, message: str): ...
    def error(self, message: str): ...

class GlobResults(list):
    """Enhanced list of glob results with additional methods."""
    def __init__(self, results): ...

class StreamBufferer:
    """Advanced: Internal buffering implementation for I/O streams."""
    def __init__(self, buffer_size: int = 0, encoding: str = 'utf-8'): ...