CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sh

Python subprocess replacement that allows calling system commands as Python functions

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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'): ...
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/sh@2.2.x
Publish Source
CLI
Badge
tessl/pypi-sh badge