CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-sh

Python subprocess replacement that allows calling system commands as Python functions

Pending
Overview
Eval results
Files

contrib.mddocs/

Contrib Commands

Enhanced command wrappers that provide optimized defaults and specialized functionality for common tools. The contrib system offers pre-configured versions of popular commands with better defaults and additional features.

Capabilities

Git Integration

Enhanced git command with optimized settings for programmatic usage.

@contrib("git")
def git(orig):
    """
    Git command optimized for programmatic usage.
    
    Returns:
    Command: Git command with TTY output disabled for cleaner programmatic usage
    """

Usage examples:

import sh

# Use contrib git for cleaner output
git = sh.contrib.git
result = git("status", "--porcelain")
print("Modified files:", result.strip())

# Compare with regular git (may have TTY formatting)
regular_git = sh.git
git_output = regular_git("log", "--oneline", "-n", "5")

# Contrib git works better for parsing
commits = git("log", "--format=%H %s", "-n", "10").strip().split('\n')
for commit in commits:
    hash_part, message = commit.split(' ', 1)
    print(f"Commit: {hash_part[:8]} - {message}")

Bash Command Execution

Pre-configured bash command for executing shell scripts and commands.

@contrib("bash")
def bash(orig):
    """
    Bash command pre-configured with -c flag for script execution.
    
    Returns:
    Command: Bash command ready for script execution
    """

Usage examples:

import sh

# Execute bash commands and scripts
bash = sh.contrib.bash
result = bash("echo 'Hello from bash'; ls -la | wc -l")
print("Bash output:", result)

# Execute complex shell pipelines
pipeline_result = bash("ps aux | grep python | wc -l")
python_processes = int(pipeline_result.strip())
print(f"Python processes running: {python_processes}")

# Execute multi-line bash scripts
script = '''
for i in {1..5}; do
    echo "Count: $i"
done
'''
bash(script)

Sudo with Password Handling

Enhanced sudo command with automatic password prompting and password parameter support.

@contrib("sudo")
def sudo(orig):
    """
    Sudo command with enhanced password handling.
    
    Features:
    - Automatic password prompting using getpass
    - Password parameter support
    - Uses -S flag for stdin password input
    
    Returns:
    Command: Enhanced sudo command with password handling
    """

Usage examples:

import sh
import getpass

# Interactive password prompting (secure)
sudo = sh.contrib.sudo
sudo("apt", "update")  # Will prompt for password securely

# Programmatic password (use carefully)
password = getpass.getpass("Enter sudo password: ")
sudo("systemctl", "restart", "nginx", password=password)

# File operations requiring sudo
sudo("chown", "www-data:www-data", "/var/www/html/uploads/")
sudo("chmod", "755", "/var/www/html/")

# System administration tasks
result = sudo("systemctl", "status", "apache2")
if "active (running)" in result:
    print("Apache is running")
else:
    print("Apache is not running")

SSH with Interactive Support

Advanced SSH command with automatic password handling and interactive session support.

@contrib("ssh")
def ssh(orig):
    """
    SSH command with enhanced interactive capabilities.
    
    Features:
    - Automatic password authentication
    - Interactive session management
    - Login success detection
    - Session content tracking
    
    Returns:
    Command: Enhanced SSH command with interactive features
    """

Usage examples:

import sh

# Note: SSH contrib is primarily for interactive use
# For basic SSH commands, regular sh.ssh may be sufficient
ssh = sh.contrib.ssh

# Interactive SSH session (advanced usage)
# This is primarily used for complex interactive scenarios
# Most users should use regular sh.ssh for simple commands

# Example of remote command execution
try:
    result = sh.ssh("user@remote-server", "uptime")
    print("Remote uptime:", result.strip())
except sh.ErrorReturnCode as e:
    print("SSH failed:", e)

# For file transfers, consider using sh.scp or sh.rsync
sh.scp("local_file.txt", "user@remote:/tmp/")
sh.rsync("-av", "local_dir/", "user@remote:backup/")

Creating Custom Contrib Commands

Extend the contrib system with your own enhanced command wrappers.

import sh

# Example: Enhanced docker command with common defaults
@sh.contrib("docker")
def docker(orig):
    """Docker command with common defaults."""
    # Add common flags and settings
    cmd = orig.bake("--rm")  # Always remove containers after exit
    return cmd

# Example: Enhanced curl with better defaults
@sh.contrib("curl") 
def curl(orig):
    """Curl with better defaults for API usage."""
    cmd = orig.bake(
        "-s",           # Silent mode
        "-L",           # Follow redirects
        "-f",           # Fail on HTTP errors
        "--max-time", "30"  # 30 second timeout
    )
    return cmd

# Usage
docker = sh.contrib.docker
curl = sh.contrib.curl

# These now have the enhanced defaults
container_output = docker("run", "ubuntu", "echo", "hello")
api_response = curl("https://api.example.com/status")

Accessing Contrib Commands

Multiple ways to access and use contrib commands in your applications.

import sh

# Method 1: Direct access
git_contrib = sh.contrib.git
result = git_contrib("status")

# Method 2: Import pattern
from sh.contrib import git, sudo, bash
git_status = git("status", "--porcelain")
sudo("systemctl", "restart", "nginx")
bash_result = bash("echo $HOME; pwd")

# Method 3: Dynamic access
command_name = "git"
contrib_cmd = getattr(sh.contrib, command_name)
output = contrib_cmd("log", "--oneline", "-n", "5")

# Check available contrib commands
available_contribs = [cmd for cmd in dir(sh.contrib) if not cmd.startswith('_')]
print("Available contrib commands:", available_contribs)

Types

class Contrib(ModuleType):
    """
    Module type for contrib command system.
    
    Provides decorator interface for creating enhanced command wrappers.
    """
    
    @classmethod
    def __call__(cls, name: str):
        """
        Decorator for creating contrib command wrappers.
        
        Parameters:
        - name: str = name of the command to enhance
        
        Returns:
        callable: Decorator function for command enhancement
        """

Install with Tessl CLI

npx tessl i tessl/pypi-sh

docs

command-execution.md

contrib.md

error-handling.md

index.md

io-handling.md

process-management.md

utilities.md

tile.json